mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-09-10 14:11:58 +00:00
Compare commits
128 Commits
autoformat
...
14.52
Author | SHA1 | Date | |
---|---|---|---|
|
e8599ec433 | ||
|
90b4263caf | ||
|
c677fc8399 | ||
|
60a8d0008e | ||
|
4f1397eeee | ||
|
8862645dea | ||
|
767a3d0e61 | ||
|
8dd6ce48dc | ||
|
89de2e4677 | ||
|
2039018ce5 | ||
|
3829d39087 | ||
|
2561ad6f2b | ||
|
83d5294286 | ||
|
10ff5f3366 | ||
|
c6551f09c1 | ||
|
88d891fe18 | ||
|
3b474bdf94 | ||
|
56268adce9 | ||
|
2fe2a043ef | ||
|
5eac104f4b | ||
|
e135e2cbc2 | ||
|
f011e6b6f7 | ||
|
1a43942240 | ||
|
3b48266545 | ||
|
c0753e3285 | ||
|
1f18805733 | ||
|
ce8b045700 | ||
|
2f66e95d23 | ||
|
db40fa5d58 | ||
|
8e19d8f2f6 | ||
|
6c1318b161 | ||
|
ecab12308a | ||
|
e3ddcf09ab | ||
|
cb37269686 | ||
|
2de613bdc1 | ||
|
a576aa40a5 | ||
|
a11e80897f | ||
|
425f38ccca | ||
|
fdf73e4538 | ||
|
d54e666d79 | ||
|
a1151d2918 | ||
|
fb37f18e57 | ||
|
9fefc17eef | ||
|
17ad517268 | ||
|
4468faae99 | ||
|
414a13dd8d | ||
|
ff80318068 | ||
|
4fb119c3fb | ||
|
5b7029b130 | ||
|
d71289b3e2 | ||
|
b48f6bc49a | ||
|
275256e3e8 | ||
|
4314a30f3a | ||
|
bf5d1939c2 | ||
|
5bec8149a5 | ||
|
a9627c0c26 | ||
|
b57dda3364 | ||
|
67af102fc0 | ||
|
20a617adef | ||
|
5947ae891a | ||
|
26957c7b81 | ||
|
f212e8ff81 | ||
|
512540e32e | ||
|
bafc3fb3e4 | ||
|
51dd968069 | ||
|
d698619bff | ||
|
be4fa79c76 | ||
|
2c51af33d3 | ||
|
8f73a82358 | ||
|
ee07bb635f | ||
|
9ee35d793b | ||
|
9ebc8c3cbe | ||
|
53c70cee66 | ||
|
46da760cb2 | ||
|
f6d005c15c | ||
|
3a86e5c2f0 | ||
|
244ad60c5f | ||
|
fc6cdf8d6b | ||
|
18ab090f4e | ||
|
a9e3221883 | ||
|
edfad6b4ab | ||
|
fecdca496a | ||
|
e4fd6d7606 | ||
|
7b8c865f2b | ||
|
38a5664cf3 | ||
|
c8b0a6dbd0 | ||
|
868672e7ea | ||
|
e712d188fe | ||
|
bdedc23c95 | ||
|
aff84374c4 | ||
|
779731018d | ||
|
e242f5db98 | ||
|
68cde24419 | ||
|
7daef9ee21 | ||
|
db52b87849 | ||
|
cf379f3baa | ||
|
de04ce6944 | ||
|
caf5fdede4 | ||
|
2d4140ea64 | ||
|
3c928a4928 | ||
|
599f5727a0 | ||
|
7ac5cb1807 | ||
|
d311ef2c5f | ||
|
6f820e2c25 | ||
|
e515dacab1 | ||
|
5041249f03 | ||
|
1b26e3a937 | ||
|
a2d9afcecc | ||
|
577de6bf4c | ||
|
f71f53c988 | ||
|
7e4d72a66a | ||
|
142f99b2a2 | ||
|
1b0ddb1e74 | ||
|
4fa0157594 | ||
|
c1196ed8e9 | ||
|
90a69173bd | ||
|
cb0a07d5da | ||
|
77e721d66a | ||
|
25d2a51254 | ||
|
54fe4bb969 | ||
|
7e719cae80 | ||
|
157a6ba1c5 | ||
|
4fc165150a | ||
|
d574d05066 | ||
|
f66426bb60 | ||
|
b846ccd85e | ||
|
09fc6f1e25 | ||
|
630f553fce |
5
.gitignore
vendored
5
.gitignore
vendored
@@ -24,16 +24,17 @@ target
|
||||
*.log.*
|
||||
|
||||
# Mobile Tools for Java (J2ME)
|
||||
|
||||
.mtj
|
||||
.tmp/
|
||||
|
||||
# Package Files #
|
||||
|
||||
*.jar
|
||||
*.war
|
||||
*.ear
|
||||
|
||||
# maven-shade-plugin for mmt tool
|
||||
dependency-reduced-pom.xml
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
|
||||
hs_err_pid*
|
||||
|
23
.travis.yml
23
.travis.yml
@@ -43,6 +43,11 @@ install: travis_retry travis_wait 40 bash scripts/travis/build.sh
|
||||
|
||||
jobs:
|
||||
include:
|
||||
- name: "Source Clear Scan (SCA)"
|
||||
if: branch = master OR branch =~ /release\/.*/
|
||||
# Run Veracode
|
||||
install: skip
|
||||
script: travis_wait 30 bash scripts/travis/source_clear.sh
|
||||
|
||||
- name: "Core, Data-Model, Repository - AllUnitTestsSuite - Build and test"
|
||||
if: commit_message !~ /\[skip repo\]/
|
||||
@@ -55,7 +60,7 @@ jobs:
|
||||
before_script:
|
||||
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:13.3 postgres -c 'max_connections=300'
|
||||
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.16.1
|
||||
- docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:2.5.3
|
||||
- docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:2.5.4
|
||||
script: travis_wait 20 mvn -B test -pl repository -Dtest=AppContext01TestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
|
||||
|
||||
- name: "Repository - AppContext02TestSuite"
|
||||
@@ -70,7 +75,7 @@ jobs:
|
||||
before_script:
|
||||
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:13.3 postgres -c 'max_connections=300'
|
||||
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.16.1
|
||||
- docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:2.5.3
|
||||
- docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:2.5.4
|
||||
script: travis_wait 20 mvn -B test -pl repository -Dtest=AppContext03TestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
|
||||
|
||||
- name: "Repository - AppContext04TestSuite"
|
||||
@@ -78,7 +83,7 @@ jobs:
|
||||
before_script:
|
||||
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:13.3 postgres -c 'max_connections=300'
|
||||
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.16.1
|
||||
- docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:2.5.3
|
||||
- docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:2.5.4
|
||||
script: travis_wait 20 mvn -B test -pl repository -Dtest=AppContext04TestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
|
||||
|
||||
- name: "Repository - AppContext05TestSuite"
|
||||
@@ -97,7 +102,7 @@ jobs:
|
||||
before_script:
|
||||
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:13.3 postgres -c 'max_connections=300'
|
||||
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.16.1
|
||||
- docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:2.5.3
|
||||
- docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:2.5.4
|
||||
script: travis_wait 20 mvn -B test -pl repository -Dtest=AppContext06TestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
|
||||
|
||||
- name: "Repository - AppContextExtraTestSuite"
|
||||
@@ -105,7 +110,7 @@ jobs:
|
||||
before_script:
|
||||
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:13.3 postgres -c 'max_connections=300'
|
||||
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.16.1
|
||||
- docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:2.5.3
|
||||
- docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:2.5.4
|
||||
script: travis_wait 20 mvn -B test -pl repository -Dtest=AppContextExtraTestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
|
||||
|
||||
- name: "Repository - MiscContextTestSuite"
|
||||
@@ -113,7 +118,7 @@ jobs:
|
||||
before_script:
|
||||
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:13.3 postgres -c 'max_connections=300'
|
||||
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.16.1
|
||||
- docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:2.5.3
|
||||
- docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:2.5.4
|
||||
script: travis_wait 20 mvn -B test -pl repository -Dtest=MiscContextTestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
|
||||
|
||||
- name: "Repository - SearchTestSuite"
|
||||
@@ -236,7 +241,7 @@ jobs:
|
||||
before_script:
|
||||
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:13.3 postgres -c 'max_connections=300'
|
||||
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.16.1
|
||||
- docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:2.5.3
|
||||
- docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:2.5.4
|
||||
script: travis_wait 20 mvn -B test -pl remote-api -Dtest=AppContext02TestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
|
||||
|
||||
- name: "Remote-api - AppContext03TestSuite"
|
||||
@@ -244,7 +249,7 @@ jobs:
|
||||
before_script:
|
||||
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:13.3 postgres -c 'max_connections=300'
|
||||
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.16.1
|
||||
- docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:2.5.3
|
||||
- docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:2.5.4
|
||||
script: travis_wait 20 mvn -B test -pl remote-api -Dtest=AppContext03TestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
|
||||
|
||||
- name: "Remote-api - AppContext04TestSuite"
|
||||
@@ -252,7 +257,7 @@ jobs:
|
||||
before_script:
|
||||
- docker run -d -p 5433:5432 -e POSTGRES_PASSWORD=alfresco -e POSTGRES_USER=alfresco -e POSTGRES_DB=alfresco postgres:13.3 postgres -c 'max_connections=300'
|
||||
- docker run -d -p 61616:61616 -p 5672:5672 alfresco/alfresco-activemq:5.16.1
|
||||
- docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:2.5.3
|
||||
- docker run -d -p 8090:8090 -e JAVA_OPTS=" -Xms256m -Xmx256m" alfresco/alfresco-transform-core-aio:2.5.4
|
||||
script: travis_wait 20 mvn -B test -pl remote-api -Dtest=AppContext04TestSuite -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql://localhost:5433/alfresco -Ddb.username=alfresco -Ddb.password=alfresco
|
||||
|
||||
- name: "Remote-api - AppContextExtraTestSuite"
|
||||
|
74
README.md
74
README.md
@@ -2,13 +2,6 @@
|
||||
|
||||
[](https://travis-ci.com/Alfresco/alfresco-community-repo)
|
||||
|
||||
This project contains the bulk of the [Alfresco Content Services Repository](https://community.alfresco.com/docs/DOC-6385-project-overview-repository) code.
|
||||
|
||||
To make the development process simpler, it brings together code historically in `alfresco-core`,
|
||||
`alfresco-data-madel`, `alfresco-repository`, `alfresco-remote-api` and repository specific
|
||||
tests and war file creation from `acs-community-packaging`. They exist as sub projects within the Maven Reactor and still
|
||||
create the same artifacts.
|
||||
|
||||
#### Alfresco Core
|
||||
|
||||
Alfresco Core is a library packaged as a jar file which contains the following:
|
||||
@@ -16,8 +9,6 @@ Alfresco Core is a library packaged as a jar file which contains the following:
|
||||
* Canned queries interface and supporting classes
|
||||
* Generic encryption supporting classes
|
||||
|
||||
Version 7 of the library uses Spring 5, Quartz 2.3 and does not have Hibernate dependency.
|
||||
|
||||
#### Alfresco Data Model
|
||||
Data model is a library packaged as a jar file which contains the following:
|
||||
* Dictionary, Repository and Search Services interfaces
|
||||
@@ -31,14 +22,6 @@ Repository is a library packaged as a jar file which contains the following:
|
||||
* Various Service implementations
|
||||
* Utility classes
|
||||
|
||||
Tests are combined into test classes split by test type or Spring application context used in the test, see classes
|
||||
in _src/test/java/org/alfresco_. All of these classes as well as individual tests can be run by specifying the test
|
||||
class name and a set of DB connection properties. Check the travis.yml file for docker images that should be started
|
||||
to provide a suitable test environment. For example:
|
||||
~~~
|
||||
mvn clean test -Dtest=SomeRepoTest -Ddb.driver=org.postgresql.Driver -Ddb.name=alfresco -Ddb.url=jdbc:postgresql:alfresco -Ddb.username=alfresco -Ddb.password=alfresco
|
||||
~~~
|
||||
|
||||
#### Alfresco Remote API
|
||||
|
||||
Remote API is a library packaged as a jar file which contains the following:
|
||||
@@ -46,13 +29,10 @@ Remote API is a library packaged as a jar file which contains the following:
|
||||
* WebScript implementations including [V1 REST APIs](https://community.alfresco.com/community/ecm/blog/2017/05/02/v1-rest-api-10-things-you-should-know)
|
||||
* [OpenCMIS](https://chemistry.apache.org/java/opencmis.html) implementations
|
||||
|
||||
Like the `alfresco-repository` tests are combined in test classes split by test type or Spring application context used
|
||||
in the test.
|
||||
|
||||
#### Artifacts
|
||||
The artifacts can be obtained by:
|
||||
* downloading from [Alfresco maven repository](https://artifacts.alfresco.com/nexus/content/groups/public)
|
||||
* getting as Maven dependency by adding the dependency to your pom file:
|
||||
* as Maven dependency by adding the dependency to your pom file:
|
||||
~~~
|
||||
<dependency>
|
||||
<groupId>org.alfresco</groupId>
|
||||
@@ -94,40 +74,24 @@ and Alfresco maven repository:
|
||||
~~~
|
||||
The SNAPSHOT versions of the artifact are not published.
|
||||
|
||||
All current source versions are held in github. Historic versions can be found in [Alfresco SVN](https://svn.alfresco.com/repos/alfresco-open-mirror/services/alfresco-core/)
|
||||
|
||||
### Contributing guide
|
||||
Please use [this guide](CONTRIBUTING.md) to make a contribution to the project.
|
||||
|
||||
## Setting up your development environment
|
||||
Although it is possible to work on individual github projects, we recommend working on the `alfresco-community-repo`
|
||||
and `acs-community-packaging` in a single Intellij IDEA project. They depend on each other and typically you will
|
||||
want to make changes to both of them if you are changing the repository code.
|
||||
|
||||
~~~
|
||||
mkdir work
|
||||
cd work
|
||||
git clone git@github.com:Alfresco/alfresco-community-repo.git
|
||||
git clone git@github.com:Alfresco/acs-community-packaging.git
|
||||
~~~
|
||||
If you wish to build these projects from the command line, use the following commands.
|
||||
~~~
|
||||
cd alfresco-community-repo
|
||||
mvn clean install -Pbuild-docker-images -DskipTests=true -Dversion.edition=Community
|
||||
cd ..
|
||||
|
||||
cd acs-community-packaging
|
||||
mvn clean install -Pbuild-docker-images -Dmaven.javadoc.skip=true
|
||||
cd ..
|
||||
~~~
|
||||
In Intellij IDEA, create a new project using the `work` directory as the source.
|
||||
* File > New Project from Existing Sources > .../work > Maven
|
||||
## Setting up and building your development environment
|
||||
See the [Development Tomcat Environment](https://github.com/Alfresco/acs-community-packaging/tree/master/dev/README.md)
|
||||
page which will show you how to try out your repository changes in a local tomcat instance.
|
||||
If you wish to use Docker images, take a look at the aliases ending in `D` and the docker-compose files in this
|
||||
project's test modules.
|
||||
|
||||
## Branches
|
||||
As multiple projects have been combined, branch names use the ACS version they are targeting.
|
||||
For example the code used to create the repository in ACS 6.2.1 is a branch called `releases/6.2.1`.
|
||||
This project has a branch for each ACS release. For example the code in ACS 6.2.1 is a
|
||||
branch called `releases/6.2.2`. In addition to the original 6.2.2 release it will also contain Hot Fixes
|
||||
added later. The latest unreleased code is on the `master` branch. There are also `.N` branches, such as
|
||||
`releases/7.1.N` on which we gather unreleased fixes for future service pack releases. They do not indicate
|
||||
that one is planned.
|
||||
|
||||
The actual version number of the **repository artifacts** created by `alfresco-community-repo` are however different.
|
||||
For example `release/6.2.1` artifacts are `7.183.x`. This adds some complexity, but ensures that
|
||||
version numbers do not go backwards in existing releases. It also provides some level of
|
||||
independence between the repository and other ACS components.
|
||||
For historic reasons the version of artifacts created on each branch do not match the ACS version.
|
||||
For example artifact in ACS 7.2.0 will be `14.<something>`.
|
||||
|
||||
The enterprise projects which extend the `alfresco-community-repo` use the same branch names and leading
|
||||
artifact version number.
|
||||
|
||||
### Contributing guide
|
||||
Please use [this guide](CONTRIBUTING.md) to make a contribution to the project.
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-amps</artifactId>
|
||||
<version>14.15-SNAPSHOT</version>
|
||||
<version>14.52</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-governance-services-community-parent</artifactId>
|
||||
<version>14.15-SNAPSHOT</version>
|
||||
<version>14.52</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-governance-services-automation-community-repo</artifactId>
|
||||
<version>14.15-SNAPSHOT</version>
|
||||
<version>14.52</version>
|
||||
</parent>
|
||||
|
||||
|
||||
|
@@ -0,0 +1,89 @@
|
||||
# dataprep related
|
||||
alfresco.scheme=http
|
||||
alfresco.server=localhost
|
||||
alfresco.port=8082
|
||||
|
||||
# sync service related
|
||||
sync.scheme=http
|
||||
sync.server=localhost
|
||||
sync.port=9090
|
||||
|
||||
# Solr Server Settings
|
||||
solr.scheme=http
|
||||
solr.server=localhost
|
||||
solr.port=8083
|
||||
|
||||
#Solr Indexing Time
|
||||
solrWaitTimeInSeconds=20
|
||||
|
||||
# credentials
|
||||
admin.user=admin
|
||||
admin.password=admin
|
||||
|
||||
# Identity Service configuration
|
||||
# set this property to run tests using AIS
|
||||
# identity-service.auth-server-url=http://localhost:8999/auth
|
||||
|
||||
# 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=false
|
||||
|
||||
# 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=<username>
|
||||
# testManagement.apiKey=<api-key>
|
||||
# testManagement.project=<id-of-your-project
|
||||
# testManagement.testRun=<test-run-name>
|
||||
# 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=https://alfresco.testrail.com/
|
||||
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://<your-DB-IP>:3306/alfresco
|
||||
#
|
||||
# Oracle:
|
||||
# db.url = jdbc:oracle://<your-DB-IP>:3306/alfresco
|
||||
#
|
||||
# MariaDB:
|
||||
# db.url = jdbc:mariadb://<your-DB-IP>:3306/alfresco
|
||||
#
|
||||
db.url = jdbc:mysql://${alfresco.server}:3306/alfresco
|
||||
db.username = alfresco
|
||||
db.password = alfresco
|
||||
|
||||
environment=default
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-governance-services-community-parent</artifactId>
|
||||
<version>14.15-SNAPSHOT</version>
|
||||
<version>14.52</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
|
@@ -1,4 +1,4 @@
|
||||
TRANSFORMERS_TAG=2.5.3
|
||||
TRANSFORMERS_TAG=2.5.4
|
||||
SOLR6_TAG=2.0.2-RC1
|
||||
POSTGRES_TAG=13.3
|
||||
ACTIVEMQ_TAG=5.16.1
|
||||
|
@@ -8,7 +8,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-governance-services-community-repo-parent</artifactId>
|
||||
<version>14.15-SNAPSHOT</version>
|
||||
<version>14.52</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
@@ -108,7 +108,7 @@
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-all</artifactId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
@@ -27,8 +27,9 @@
|
||||
|
||||
package org.alfresco.module.org_alfresco_module_rm.action.dm;
|
||||
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.nullable;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
@@ -352,7 +353,7 @@ public class DeclareAsVersionRecordActionUnitTest extends BaseActionUnitTest
|
||||
private void setupMockedAspects()
|
||||
{
|
||||
doReturn(true).when(mockedNodeService).exists(actionedUponNodeRef);
|
||||
doReturn(true).when(mockedDictionaryService).isSubClass(any(QName.class), eq(ContentModel.TYPE_CONTENT));
|
||||
doReturn(true).when(mockedDictionaryService).isSubClass(nullable(QName.class), eq(ContentModel.TYPE_CONTENT));
|
||||
doReturn(true).when(mockedNodeService).hasAspect(actionedUponNodeRef, ContentModel.ASPECT_VERSIONABLE);
|
||||
doReturn(false).when(mockedNodeService).hasAspect(actionedUponNodeRef, ASPECT_RECORD);
|
||||
doReturn(false).when(mockedNodeService).hasAspect(actionedUponNodeRef, ContentModel.ASPECT_WORKING_COPY);
|
||||
|
@@ -36,15 +36,13 @@ import org.junit.Test;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Matchers.isNull;
|
||||
import static org.mockito.ArgumentMatchers.anyMap;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.isNull;
|
||||
import static org.mockito.ArgumentMatchers.nullable;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.mockito.MockitoAnnotations.initMocks;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link AddToHoldAuditEvent}.
|
||||
@@ -67,8 +65,6 @@ public class AddToHoldAuditEventUnitTest extends BaseUnitTest
|
||||
@Before
|
||||
public void setUp()
|
||||
{
|
||||
initMocks(this);
|
||||
|
||||
holdNodeRef = generateNodeRef();
|
||||
String holdName = "Hold " + GUID.generate();
|
||||
|
||||
@@ -87,6 +83,6 @@ public class AddToHoldAuditEventUnitTest extends BaseUnitTest
|
||||
public void testAddToHoldCausesAuditEvent()
|
||||
{
|
||||
addToHoldAuditEvent.onAddToHold(holdNodeRef, contentNodeRef);
|
||||
verify(mockedRecordsManagementAuditService, times(1)).auditEvent(eq(contentNodeRef), any(String.class), isNull(Map.class), any(Map.class), eq(true), eq(false));
|
||||
verify(mockedRecordsManagementAuditService, times(1)).auditEvent(eq(contentNodeRef), nullable(String.class), isNull(), anyMap(), eq(true), eq(false));
|
||||
}
|
||||
}
|
||||
|
@@ -37,15 +37,13 @@ import org.junit.Test;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Matchers.isNull;
|
||||
import static org.mockito.ArgumentMatchers.anyMap;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.isNull;
|
||||
import static org.mockito.ArgumentMatchers.nullable;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.mockito.MockitoAnnotations.initMocks;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link CreateHoldAuditEvent}.
|
||||
@@ -68,8 +66,6 @@ public class CreateHoldAuditEventUnitTest extends BaseUnitTest
|
||||
@Before
|
||||
public void setUp()
|
||||
{
|
||||
initMocks(this);
|
||||
|
||||
holdNodeRef = generateNodeRef();
|
||||
String holdName = "Hold " + GUID.generate();
|
||||
String holdReason = "Reason " + GUID.generate();
|
||||
@@ -88,6 +84,6 @@ public class CreateHoldAuditEventUnitTest extends BaseUnitTest
|
||||
public void testCreateHoldCausesAuditEvent()
|
||||
{
|
||||
createHoldAuditEvent.onCreateNode(childAssociationRef);
|
||||
verify(mockedRecordsManagementAuditService, times(1)).auditEvent(eq(holdNodeRef), any(String.class), isNull(Map.class), any(Map.class));
|
||||
verify(mockedRecordsManagementAuditService, times(1)).auditEvent(eq(holdNodeRef), nullable(String.class), isNull(), anyMap());
|
||||
}
|
||||
}
|
||||
|
@@ -34,18 +34,15 @@ import org.alfresco.util.GUID;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Matchers;
|
||||
import org.mockito.Mock;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Matchers.isNull;
|
||||
import static org.mockito.ArgumentMatchers.anyMap;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.isNull;
|
||||
import static org.mockito.ArgumentMatchers.nullable;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.mockito.MockitoAnnotations.initMocks;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link DeleteHoldAuditEvent}.
|
||||
@@ -67,8 +64,6 @@ public class DeleteHoldAuditEventUnitTest extends BaseUnitTest
|
||||
@Before
|
||||
public void setUp()
|
||||
{
|
||||
initMocks(this);
|
||||
|
||||
holdNodeRef = generateNodeRef();
|
||||
String holdName = "Hold " + GUID.generate();
|
||||
|
||||
@@ -84,6 +79,6 @@ public class DeleteHoldAuditEventUnitTest extends BaseUnitTest
|
||||
{
|
||||
deleteHoldAuditEvent.beforeDeleteNode(holdNodeRef);
|
||||
verify(mockedRecordsManagementAuditService, times(1))
|
||||
.auditEvent(eq(holdNodeRef), any(String.class), any(Map.class), isNull(Map.class), Matchers.eq(true), Matchers.eq(false));
|
||||
.auditEvent(eq(holdNodeRef), nullable(String.class), anyMap(), isNull(), eq(true), eq(false));
|
||||
}
|
||||
}
|
||||
|
@@ -27,25 +27,24 @@
|
||||
|
||||
package org.alfresco.module.org_alfresco_module_rm.audit.event;
|
||||
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Matchers.isNull;
|
||||
import static org.mockito.ArgumentMatchers.anyMap;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.isNull;
|
||||
import static org.mockito.ArgumentMatchers.nullable;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.mockito.MockitoAnnotations.initMocks;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.util.GUID;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link RemoveFromHoldAuditEvent}.
|
||||
@@ -53,6 +52,7 @@ import org.mockito.Mock;
|
||||
* @author Chris Shields
|
||||
* @since 3.3
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class RemoveFromHoldAuditEventUnitTest extends BaseUnitTest
|
||||
{
|
||||
@InjectMocks
|
||||
@@ -70,16 +70,14 @@ public class RemoveFromHoldAuditEventUnitTest extends BaseUnitTest
|
||||
@Before
|
||||
public void setUp()
|
||||
{
|
||||
initMocks(this);
|
||||
|
||||
holdNodeRef = generateNodeRef();
|
||||
String holdName = "Hold " + GUID.generate();
|
||||
|
||||
contentNodeRef = generateNodeRef();
|
||||
String contentName = "Content " + GUID.generate();
|
||||
|
||||
when(mockedNodeService.getProperty(holdNodeRef, PROP_NAME)).thenReturn(holdName);
|
||||
when(mockedNodeService.getProperty(contentNodeRef, PROP_NAME)).thenReturn(contentName);
|
||||
lenient().when(mockedNodeService.getProperty(holdNodeRef, PROP_NAME)).thenReturn(holdName);
|
||||
lenient().when(mockedNodeService.getProperty(contentNodeRef, PROP_NAME)).thenReturn(contentName);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -89,7 +87,7 @@ public class RemoveFromHoldAuditEventUnitTest extends BaseUnitTest
|
||||
public void testRemoveFromHoldCausesAuditEvent()
|
||||
{
|
||||
removeFromHoldAuditEvent.onRemoveFromHold(holdNodeRef, contentNodeRef);
|
||||
verify(mockedRecordsManagementAuditService, times(1)).auditEvent(eq(contentNodeRef), any(String.class), any(Map.class), isNull(Map.class), eq(true));
|
||||
verify(mockedRecordsManagementAuditService, times(1)).auditEvent(eq(contentNodeRef), nullable(String.class), anyMap(), isNull(), eq(true));
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -28,14 +28,14 @@
|
||||
package org.alfresco.module.org_alfresco_module_rm.forms;
|
||||
|
||||
import static org.alfresco.module.org_alfresco_module_rm.test.util.AlfMock.generateQName;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyListOf;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyList;
|
||||
import static org.mockito.ArgumentMatchers.nullable;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyZeroInteractions;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -45,7 +45,6 @@ import java.util.Map;
|
||||
|
||||
import org.alfresco.module.org_alfresco_module_rm.admin.RecordsManagementAdminService;
|
||||
import org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest;
|
||||
import org.alfresco.repo.forms.Field;
|
||||
import org.alfresco.repo.forms.FieldDefinition;
|
||||
import org.alfresco.repo.forms.Form;
|
||||
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
||||
@@ -81,7 +80,7 @@ public class RecordsManagementTypeFormFilterUnitTest extends BaseUnitTest
|
||||
public void testAddCustomRMPropertiesNoneFound()
|
||||
{
|
||||
typeFormFilter.addCustomRMProperties(MY_CUSTOM_TYPE, mockForm);
|
||||
verifyZeroInteractions(mockForm);
|
||||
verifyNoMoreInteractions(mockForm);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -130,8 +129,8 @@ public class RecordsManagementTypeFormFilterUnitTest extends BaseUnitTest
|
||||
|
||||
typeFormFilter.afterGenerate(mockTypeDefinition, null, null, mockForm, null);
|
||||
|
||||
verify(mockedIdentifierService).generateIdentifier(any(QName.class), any(NodeRef.class));
|
||||
verify(idDef).setDefaultValue(anyString());
|
||||
verify(mockedIdentifierService).generateIdentifier(nullable(QName.class), nullable(NodeRef.class));
|
||||
verify(idDef).setDefaultValue(nullable(String.class));
|
||||
verify(vrDef).setDefaultValue(Boolean.FALSE.toString());
|
||||
verify(rpDef).setDefaultValue("none|0");
|
||||
}
|
||||
@@ -162,7 +161,7 @@ public class RecordsManagementTypeFormFilterUnitTest extends BaseUnitTest
|
||||
typeFormFilter.addCustomRMProperties(MY_CUSTOM_TYPE, mockForm);
|
||||
|
||||
// ensure that two custom properties have been added to the form
|
||||
verify(mockForm, times(1)).addFields(anyListOf(Field.class));
|
||||
verify(mockForm, times(1)).addFields(anyList());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -30,16 +30,16 @@ package org.alfresco.module.org_alfresco_module_rm.job;
|
||||
import static org.alfresco.module.org_alfresco_module_rm.test.util.AlfMock.generateQName;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyMap;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.anyMap;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
import static org.mockito.Mockito.verifyZeroInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.Arrays;
|
||||
@@ -57,7 +57,6 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Matchers;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
@@ -98,7 +97,7 @@ public class DispositionLifecycleJobExecuterUnitTest extends BaseUnitTest
|
||||
return callback.execute();
|
||||
};
|
||||
doAnswer(doInTransactionAnswer).when(mockedRetryingTransactionHelper).doInTransaction(any(RetryingTransactionCallback.class),
|
||||
Matchers.anyBoolean(), Matchers.anyBoolean());
|
||||
anyBoolean(), anyBoolean());
|
||||
|
||||
// setup data
|
||||
List<String> dispositionActions = buildList(CUTOFF, RETAIN);
|
||||
@@ -141,7 +140,7 @@ public class DispositionLifecycleJobExecuterUnitTest extends BaseUnitTest
|
||||
verifyQueryTimes(1);
|
||||
|
||||
// ensure nothing else happens becuase we have no results
|
||||
verifyZeroInteractions(mockedNodeService, mockedRecordFolderService, mockedRetryingTransactionHelper);
|
||||
verifyNoMoreInteractions(mockedNodeService, mockedRecordFolderService, mockedRetryingTransactionHelper);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -178,7 +177,7 @@ public class DispositionLifecycleJobExecuterUnitTest extends BaseUnitTest
|
||||
// ensure work is executed in transaction for each node processed
|
||||
verify(mockedNodeService, times(2)).exists(any(NodeRef.class));
|
||||
verify(mockedRetryingTransactionHelper, times(2)).doInTransaction(any(RetryingTransactionCallback.class),
|
||||
Matchers.anyBoolean(), Matchers.anyBoolean());
|
||||
anyBoolean(), anyBoolean());
|
||||
|
||||
// ensure each node is process correctly
|
||||
verify(mockedNodeService, times(1)).getProperty(node1, RecordsManagementModel.PROP_DISPOSITION_ACTION);
|
||||
@@ -186,7 +185,7 @@ public class DispositionLifecycleJobExecuterUnitTest extends BaseUnitTest
|
||||
|
||||
// ensure no more interactions
|
||||
verifyNoMoreInteractions(mockedNodeService);
|
||||
verifyZeroInteractions(mockedRecordsManagementActionService);
|
||||
verifyNoMoreInteractions(mockedRecordsManagementActionService);
|
||||
|
||||
}
|
||||
|
||||
@@ -216,7 +215,7 @@ public class DispositionLifecycleJobExecuterUnitTest extends BaseUnitTest
|
||||
|
||||
// ensure no more interactions
|
||||
verifyNoMoreInteractions(mockedNodeService);
|
||||
verifyZeroInteractions(mockedRecordsManagementActionService);
|
||||
verifyNoMoreInteractions(mockedRecordsManagementActionService);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -258,7 +257,7 @@ public class DispositionLifecycleJobExecuterUnitTest extends BaseUnitTest
|
||||
// ensure work is executed in transaction for each node processed
|
||||
verify(mockedNodeService, times(2)).exists(any(NodeRef.class));
|
||||
verify(mockedRetryingTransactionHelper, times(2)).doInTransaction(any(RetryingTransactionCallback.class),
|
||||
Matchers.anyBoolean(), Matchers.anyBoolean());
|
||||
anyBoolean(), anyBoolean());
|
||||
|
||||
// ensure each node is process correctly
|
||||
// node1
|
||||
@@ -307,7 +306,7 @@ public class DispositionLifecycleJobExecuterUnitTest extends BaseUnitTest
|
||||
|
||||
// mock the search service to return the right page
|
||||
when(mockedSearchService.query(any(SearchParameters.class))).thenAnswer((Answer<ResultSet>) invocation -> {
|
||||
SearchParameters params = invocation.getArgumentAt(0, SearchParameters.class);
|
||||
SearchParameters params = invocation.getArgument(0, SearchParameters.class);
|
||||
if (params.getSkipCount() == 0)
|
||||
{
|
||||
// mock first page
|
||||
|
@@ -27,17 +27,15 @@
|
||||
package org.alfresco.module.org_alfresco_module_rm.model.rma.aspect;
|
||||
|
||||
import static org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel.ASPECT_HELD_CHILDREN;
|
||||
import static org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel.ASPECT_RECORD;
|
||||
import static org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel.PROP_HELD_CHILDREN_COUNT;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyMap;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyMap;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.module.org_alfresco_module_rm.freeze.FreezeService;
|
||||
@@ -51,24 +49,22 @@ import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
/**
|
||||
* Test class for frozen aspect
|
||||
* @author Ross Gale
|
||||
* @since 3.2
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class FrozenAspectUnitTest
|
||||
{
|
||||
@Mock
|
||||
private NodeService mockNodeService;
|
||||
|
||||
@Mock
|
||||
private ApplicationContext mockApplicationContext;
|
||||
|
||||
@Mock
|
||||
private ChildAssociationRef mockChildAssociationRef;
|
||||
|
||||
@@ -90,9 +86,6 @@ public class FrozenAspectUnitTest
|
||||
@Mock
|
||||
private ChildAssociationRef mockOldRef;
|
||||
|
||||
@Mock
|
||||
private Set mockSet;
|
||||
|
||||
@Mock
|
||||
private PropertyModificationAllowedCheck mockPropertyModificationAllowedCheck;
|
||||
|
||||
@@ -110,18 +103,17 @@ public class FrozenAspectUnitTest
|
||||
@Before
|
||||
public void setUp()
|
||||
{
|
||||
MockitoAnnotations.initMocks(this);
|
||||
when(mockNodeService.exists(record)).thenReturn(true);
|
||||
when(mockNodeService.getType(record)).thenReturn(ContentModel.TYPE_CONTENT);
|
||||
when(mockedNodeTypeUtility.instanceOf(mockNodeService.getType(record), ContentModel.TYPE_CONTENT)).thenReturn(true);
|
||||
when(mockNodeService.exists(content)).thenReturn(true);
|
||||
when(mockNodeService.hasAspect(folder, ASPECT_HELD_CHILDREN)).thenReturn(true);
|
||||
when(mockNodeService.getProperty(folder, PROP_HELD_CHILDREN_COUNT)).thenReturn(1);
|
||||
when(mockApplicationContext.getBean("dbNodeService")).thenReturn(mockNodeService);
|
||||
when(mockFreezeService.isFrozen(content)).thenReturn(false);
|
||||
children.add(mockChildRef);
|
||||
when(mockNodeService.getChildAssocs(content)).thenReturn(children);
|
||||
when(mockChildRef.isPrimary()).thenReturn(true);
|
||||
frozenAspect.setNodeService(mockNodeService);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -142,7 +134,6 @@ public class FrozenAspectUnitTest
|
||||
@Test
|
||||
public void testRemoveAspectForContent()
|
||||
{
|
||||
when(mockNodeService.hasAspect(content, ASPECT_RECORD)).thenReturn(false);
|
||||
when(mockNodeService.getType(content)).thenReturn(ContentModel.TYPE_CONTENT);
|
||||
when(mockedNodeTypeUtility.instanceOf(mockNodeService.getType(content), ContentModel.TYPE_CONTENT)).thenReturn(true);
|
||||
when(mockNodeService.getPrimaryParent(content)).thenReturn(mockChildAssociationRef);
|
||||
@@ -157,7 +148,6 @@ public class FrozenAspectUnitTest
|
||||
@Test
|
||||
public void testRemoveAspectForContentDoesntUpdateForOtherTypes()
|
||||
{
|
||||
when(mockNodeService.hasAspect(content, ASPECT_RECORD)).thenReturn(false);
|
||||
when(mockNodeService.getType(content)).thenReturn(ContentModel.TYPE_FOLDER);
|
||||
when(mockedNodeTypeUtility.instanceOf(mockNodeService.getType(content), ContentModel.TYPE_CONTENT)).thenReturn(false);
|
||||
frozenAspect.onRemoveAspect(content, null);
|
||||
@@ -233,7 +223,6 @@ public class FrozenAspectUnitTest
|
||||
@Test(expected = PermissionDeniedException.class)
|
||||
public void testBeforeMoveThrowsExceptionForFrozenNode()
|
||||
{
|
||||
when(mockOldRef.getParentRef()).thenReturn(parent);
|
||||
when(mockOldRef.getChildRef()).thenReturn(child);
|
||||
when(mockNodeService.exists(child)).thenReturn(true);
|
||||
when(mockFreezeService.isFrozen(child)).thenReturn(true);
|
||||
@@ -247,8 +236,6 @@ public class FrozenAspectUnitTest
|
||||
public void testUpdatePropertiesThrowsExceptionForFrozenNode()
|
||||
{
|
||||
when(mockFreezeService.isFrozen(content)).thenReturn(true);
|
||||
when(mockResourceHelper.getSet(content)).thenReturn(mockSet);
|
||||
when(mockSet.contains("frozen")).thenReturn(false);
|
||||
when(mockPropertyModificationAllowedCheck.check(null, null)).thenReturn(false);
|
||||
frozenAspect.onUpdateProperties(content, null, null);
|
||||
}
|
||||
|
@@ -33,7 +33,6 @@ import static org.alfresco.module.org_alfresco_module_rm.model.RecordsManagement
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.mockito.MockitoAnnotations.initMocks;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.module.org_alfresco_module_rm.security.ExtendedSecurityService;
|
||||
@@ -43,14 +42,17 @@ import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
/**
|
||||
* Unit tests for the {@link RecordAspect}.
|
||||
*
|
||||
* @author Claudia Agache
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class RecordAspectUnitTest
|
||||
{
|
||||
private static final NodeRef NODE_REF = new NodeRef("node://Ref/");
|
||||
@@ -72,7 +74,7 @@ public class RecordAspectUnitTest
|
||||
@Before
|
||||
public void setUp()
|
||||
{
|
||||
initMocks(this);
|
||||
recordAspect.setNodeService(mockNodeService);
|
||||
}
|
||||
|
||||
/** Check that the bin is duplicated before adding the aspect if the file has a copy. */
|
||||
|
@@ -45,13 +45,15 @@ import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.alfresco.util.GUID;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
/**
|
||||
* @author silviudinuta
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class NonElectronicRecordTypeUnitTest implements RecordsManagementModel, ContentModel
|
||||
{
|
||||
private final static NodeRef CHILD_NODE_REF = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE,
|
||||
@@ -74,17 +76,15 @@ public class NonElectronicRecordTypeUnitTest implements RecordsManagementModel,
|
||||
@Before
|
||||
public void setUp()
|
||||
{
|
||||
MockitoAnnotations.initMocks(this);
|
||||
MockAuthenticationUtilHelper.setup(mockAuthenticationUtil);
|
||||
when(mockedNodeService.exists(CHILD_NODE_REF)).thenReturn(true);
|
||||
when(mockedNodeService.exists(PARENT_NODE_REF)).thenReturn(true);
|
||||
|
||||
ChildAssociationRef generateChildAssociationRef = mock(ChildAssociationRef.class);
|
||||
when(generateChildAssociationRef.getParentRef()).thenReturn(PARENT_NODE_REF);
|
||||
when(generateChildAssociationRef.getChildRef()).thenReturn(CHILD_NODE_REF);
|
||||
|
||||
when(mockedNodeService.getPrimaryParent(CHILD_NODE_REF)).thenReturn(generateChildAssociationRef);
|
||||
when(mockedNodeService.getType(PARENT_NODE_REF)).thenReturn(TYPE_UNFILED_RECORD_FOLDER);
|
||||
nonElectronicRecordType.setNodeService(mockedNodeService);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@@ -27,6 +27,7 @@
|
||||
|
||||
package org.alfresco.module.org_alfresco_module_rm.script.hold;
|
||||
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -71,8 +72,8 @@ public abstract class BaseHoldWebScriptUnitTest extends BaseWebScriptUnitTest
|
||||
|
||||
// generate active content
|
||||
dmNodeRef = generateNodeRef(TYPE_CONTENT);
|
||||
when(mockedExtendedPermissionService.hasPermission(dmNodeRef, PermissionService.WRITE)).thenReturn(AccessStatus.ALLOWED);
|
||||
when(mockedDictionaryService.isSubClass(mockedNodeService.getType(dmNodeRef), ContentModel.TYPE_CONTENT)).thenReturn(true);
|
||||
lenient().when(mockedExtendedPermissionService.hasPermission(dmNodeRef, PermissionService.WRITE)).thenReturn(AccessStatus.ALLOWED);
|
||||
lenient().when(mockedDictionaryService.isSubClass(mockedNodeService.getType(dmNodeRef), ContentModel.TYPE_CONTENT)).thenReturn(true);
|
||||
|
||||
// list of active contents
|
||||
activeContents = Collections.singletonList(dmNodeRef);
|
||||
|
@@ -37,9 +37,12 @@ import java.util.List;
|
||||
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.json.JSONObject;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Spy;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.springframework.extensions.webscripts.DeclarativeWebScript;
|
||||
|
||||
/**
|
||||
@@ -48,6 +51,7 @@ import org.springframework.extensions.webscripts.DeclarativeWebScript;
|
||||
* @author Roy Wetherall
|
||||
* @since 2.2
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class HoldPutUnitTest extends BaseHoldWebScriptWithContentUnitTest
|
||||
{
|
||||
/** classpath location of ftl template for web script */
|
||||
@@ -77,6 +81,12 @@ public class HoldPutUnitTest extends BaseHoldWebScriptWithContentUnitTest
|
||||
/**
|
||||
* Test that a record can be removed from holds.
|
||||
*/
|
||||
|
||||
@Before
|
||||
public void setUp(){
|
||||
webScript.setHoldService(mockedHoldService);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void removeRecordFromHolds() throws Exception
|
||||
|
@@ -34,11 +34,12 @@ import static org.alfresco.service.cmr.security.PermissionService.GROUP_PREFIX;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anySet;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anySet;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
@@ -75,10 +76,11 @@ import org.alfresco.service.namespace.RegexQNamePattern;
|
||||
import org.alfresco.service.transaction.TransactionService;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.mockito.stubbing.Answer;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.event.ContextRefreshedEvent;
|
||||
@@ -89,6 +91,7 @@ import org.springframework.context.event.ContextRefreshedEvent;
|
||||
* @author Roy Wetherall
|
||||
* @since 2.5
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class ExtendedSecurityServiceImplUnitTest
|
||||
{
|
||||
/** service mocks*/
|
||||
@@ -145,9 +148,6 @@ public class ExtendedSecurityServiceImplUnitTest
|
||||
@SuppressWarnings("unchecked")
|
||||
@Before public void before()
|
||||
{
|
||||
// initialise mocks
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
// setup node
|
||||
nodeRef = AlfMock.generateNodeRef(mockedNodeService);
|
||||
|
||||
@@ -157,7 +157,7 @@ public class ExtendedSecurityServiceImplUnitTest
|
||||
.thenReturn(filePlan);
|
||||
|
||||
// set-up application context
|
||||
when(mockedApplicationContext.getBean("dbNodeService"))
|
||||
lenient().when(mockedApplicationContext.getBean("dbNodeService"))
|
||||
.thenReturn(mockedNodeService);
|
||||
|
||||
// setup retrying transaction helper
|
||||
@@ -199,6 +199,7 @@ public class ExtendedSecurityServiceImplUnitTest
|
||||
.forEach((a) ->
|
||||
when(mockedAuthorityService.authorityExists(a))
|
||||
.thenReturn(true));
|
||||
extendedSecurityService.setNodeService(mockedNodeService);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -481,7 +482,7 @@ public class ExtendedSecurityServiceImplUnitTest
|
||||
.thenReturn(mockedWritePagingResults);
|
||||
|
||||
// setup exact match
|
||||
when(mockedAuthorityService.authorityExists(GROUP_PREFIX + writeGroup))
|
||||
lenient().when(mockedAuthorityService.authorityExists(GROUP_PREFIX + writeGroup))
|
||||
.thenReturn(true);
|
||||
when(mockedAuthorityService.getContainedAuthorities(null, GROUP_PREFIX + readGroup, true))
|
||||
.thenReturn(Stream
|
||||
@@ -560,7 +561,7 @@ public class ExtendedSecurityServiceImplUnitTest
|
||||
.thenReturn(mockedWritePagingResults);
|
||||
|
||||
// setup exact match
|
||||
when(mockedAuthorityService.authorityExists(GROUP_PREFIX + writeGroup))
|
||||
lenient().when(mockedAuthorityService.authorityExists(GROUP_PREFIX + writeGroup))
|
||||
.thenReturn(true);
|
||||
when(mockedAuthorityService.getContainedAuthorities(null, GROUP_PREFIX + readGroup, true))
|
||||
.thenReturn(Stream
|
||||
@@ -651,7 +652,7 @@ public class ExtendedSecurityServiceImplUnitTest
|
||||
.thenReturn(mockedWritePagingResults);
|
||||
|
||||
// setup exact match
|
||||
when(mockedAuthorityService.authorityExists(GROUP_PREFIX + writeGroup))
|
||||
lenient().when(mockedAuthorityService.authorityExists(GROUP_PREFIX + writeGroup))
|
||||
.thenReturn(true);
|
||||
when(mockedAuthorityService.getContainedAuthorities(null, GROUP_PREFIX + readGroup, true))
|
||||
.thenReturn(Stream
|
||||
|
@@ -27,8 +27,9 @@
|
||||
|
||||
package org.alfresco.module.org_alfresco_module_rm.test.util;
|
||||
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.UUID;
|
||||
@@ -119,7 +120,7 @@ public class AlfMock
|
||||
public static NodeRef generateNodeRef(NodeService mockedNodeService, QName type, boolean exists)
|
||||
{
|
||||
NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, GUID.generate());
|
||||
when(mockedNodeService.exists(eq(nodeRef))).thenReturn(exists);
|
||||
lenient().when(mockedNodeService.exists(eq(nodeRef))).thenReturn(exists);
|
||||
if (type != null)
|
||||
{
|
||||
when(mockedNodeService.getType(eq(nodeRef))).thenReturn(type);
|
||||
|
@@ -28,10 +28,10 @@
|
||||
package org.alfresco.module.org_alfresco_module_rm.test.util;
|
||||
|
||||
import static org.alfresco.module.org_alfresco_module_rm.test.util.AlfMock.generateQName;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@@ -168,7 +168,7 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
// setup application context
|
||||
doReturn(mockedNodeService).when(mockedApplicationContext).getBean("dbNodeService");
|
||||
lenient().doReturn(mockedNodeService).when(mockedApplicationContext).getBean("dbNodeService");
|
||||
|
||||
// setup retrying transaction helper
|
||||
Answer<Object> doInTransactionAnswer = new Answer<Object>()
|
||||
@@ -181,7 +181,7 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel
|
||||
return callback.execute();
|
||||
}
|
||||
};
|
||||
doAnswer(doInTransactionAnswer).when(mockedRetryingTransactionHelper).<Object>doInTransaction(any(RetryingTransactionCallback.class));
|
||||
lenient().doAnswer(doInTransactionAnswer).when(mockedRetryingTransactionHelper).<Object>doInTransaction(any(RetryingTransactionCallback.class));
|
||||
|
||||
// setup mocked authentication util
|
||||
MockAuthenticationUtilHelper.setup(mockedAuthenticationUtil);
|
||||
@@ -189,15 +189,15 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel
|
||||
// setup file plan
|
||||
filePlan = generateNodeRef(TYPE_FILE_PLAN);
|
||||
setupAsFilePlanComponent(filePlan);
|
||||
doReturn(true).when(mockedFilePlanService).isFilePlan(filePlan);
|
||||
lenient().doReturn(true).when(mockedFilePlanService).isFilePlan(filePlan);
|
||||
|
||||
// setup basic file plan component
|
||||
filePlanComponent = generateNodeRef();
|
||||
setupAsFilePlanComponent(filePlanComponent);
|
||||
|
||||
// setup namespace service
|
||||
doReturn(RM_URI).when(mockedNamespaceService).getNamespaceURI(RM_PREFIX);
|
||||
doReturn(CollectionUtils.unmodifiableSet(RM_PREFIX)).when(mockedNamespaceService).getPrefixes(RM_URI);
|
||||
lenient().doReturn(RM_URI).when(mockedNamespaceService).getNamespaceURI(RM_PREFIX);
|
||||
lenient().doReturn(CollectionUtils.unmodifiableSet(RM_PREFIX)).when(mockedNamespaceService).getPrefixes(RM_URI);
|
||||
|
||||
// setup record folder and record
|
||||
recordFolder = generateRecordFolder();
|
||||
@@ -206,10 +206,10 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel
|
||||
// set record as child of record folder
|
||||
List<ChildAssociationRef> result = new ArrayList<>(1);
|
||||
result.add(new ChildAssociationRef(ContentModel.ASSOC_CONTAINS, recordFolder, generateQName(RM_URI), record, true, 1));
|
||||
doReturn(result).when(mockedNodeService).getChildAssocs(eq(recordFolder), eq(ContentModel.ASSOC_CONTAINS), any(QNamePattern.class));
|
||||
doReturn(result).when(mockedNodeService).getParentAssocs(record);
|
||||
doReturn(Collections.singletonList(recordFolder)).when(mockedRecordFolderService).getRecordFolders(record);
|
||||
doReturn(Collections.singletonList(record)).when(mockedRecordService).getRecords(recordFolder);
|
||||
lenient().doReturn(result).when(mockedNodeService).getChildAssocs(eq(recordFolder), eq(ContentModel.ASSOC_CONTAINS), any(QNamePattern.class));
|
||||
lenient().doReturn(result).when(mockedNodeService).getParentAssocs(record);
|
||||
lenient().doReturn(Collections.singletonList(recordFolder)).when(mockedRecordFolderService).getRecordFolders(record);
|
||||
lenient().doReturn(Collections.singletonList(record)).when(mockedRecordService).getRecords(recordFolder);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -221,7 +221,7 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel
|
||||
protected NodeRef generateHoldNodeRef(String name)
|
||||
{
|
||||
NodeRef hold = generateNodeRef(TYPE_HOLD);
|
||||
doReturn(name).when(mockedNodeService).getProperty(hold, ContentModel.PROP_NAME);
|
||||
lenient().doReturn(name).when(mockedNodeService).getProperty(hold, ContentModel.PROP_NAME);
|
||||
doReturn(true).when(mockedHoldService).isHold(hold);
|
||||
return hold;
|
||||
}
|
||||
@@ -235,7 +235,7 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel
|
||||
{
|
||||
NodeRef recordFolder = generateNodeRef(TYPE_RECORD_FOLDER);
|
||||
setupAsFilePlanComponent(recordFolder);
|
||||
doReturn(true).when(mockedRecordFolderService).isRecordFolder(recordFolder);
|
||||
lenient().doReturn(true).when(mockedRecordFolderService).isRecordFolder(recordFolder);
|
||||
return recordFolder;
|
||||
}
|
||||
|
||||
@@ -248,8 +248,8 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel
|
||||
{
|
||||
NodeRef record = generateNodeRef(ContentModel.TYPE_CONTENT);
|
||||
setupAsFilePlanComponent(record);
|
||||
doReturn(true).when(mockedNodeService).hasAspect(record, ASPECT_RECORD);
|
||||
doReturn(true).when(mockedRecordService).isRecord(record);
|
||||
lenient().doReturn(true).when(mockedNodeService).hasAspect(record, ASPECT_RECORD);
|
||||
lenient().doReturn(true).when(mockedRecordService).isRecord(record);
|
||||
return record;
|
||||
}
|
||||
|
||||
@@ -260,10 +260,10 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel
|
||||
*/
|
||||
protected void setupAsFilePlanComponent(NodeRef nodeRef)
|
||||
{
|
||||
doReturn(true).when(mockedNodeService).hasAspect(nodeRef, ASPECT_FILE_PLAN_COMPONENT);
|
||||
doReturn(true).when(mockedFilePlanService).isFilePlanComponent(nodeRef);
|
||||
doReturn(filePlan).when(mockedFilePlanService).getFilePlan(nodeRef);
|
||||
doReturn(filePlan).when(mockedNodeService).getProperty(nodeRef, PROP_ROOT_NODEREF);
|
||||
lenient().doReturn(true).when(mockedNodeService).hasAspect(nodeRef, ASPECT_FILE_PLAN_COMPONENT);
|
||||
lenient().doReturn(true).when(mockedFilePlanService).isFilePlanComponent(nodeRef);
|
||||
lenient().doReturn(filePlan).when(mockedFilePlanService).getFilePlan(nodeRef);
|
||||
lenient().doReturn(filePlan).when(mockedNodeService).getProperty(nodeRef, PROP_ROOT_NODEREF);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -297,7 +297,7 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel
|
||||
protected NodeRef generateCmContent(String name)
|
||||
{
|
||||
NodeRef nodeRef = generateNodeRef(ContentModel.TYPE_CONTENT, true);
|
||||
doReturn(name).when(mockedNodeService).getProperty(nodeRef, ContentModel.PROP_NAME);
|
||||
lenient().doReturn(name).when(mockedNodeService).getProperty(nodeRef, ContentModel.PROP_NAME);
|
||||
return nodeRef;
|
||||
}
|
||||
|
||||
@@ -312,11 +312,11 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel
|
||||
protected NodeRef generateNodeRef(QName type, boolean exists)
|
||||
{
|
||||
NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, GUID.generate());
|
||||
when(mockedNodeService.exists(eq(nodeRef))).thenReturn(exists);
|
||||
lenient().when(mockedNodeService.exists(eq(nodeRef))).thenReturn(exists);
|
||||
if (type != null)
|
||||
{
|
||||
when(mockedNodeService.getType(eq(nodeRef))).thenReturn(type);
|
||||
when(mockedNodeTypeUtility.instanceOf(type, type)).thenReturn(true);
|
||||
lenient().when(mockedNodeService.getType(eq(nodeRef))).thenReturn(type);
|
||||
lenient().when(mockedNodeTypeUtility.instanceOf(type, type)).thenReturn(true);
|
||||
}
|
||||
return nodeRef;
|
||||
}
|
||||
@@ -334,7 +334,7 @@ public class BaseUnitTest implements RecordsManagementModel, ContentModel
|
||||
|
||||
if (parent != null)
|
||||
{
|
||||
doReturn(parent).when(mockedChildAssociationRef).getParentRef();
|
||||
lenient().doReturn(parent).when(mockedChildAssociationRef).getParentRef();
|
||||
}
|
||||
|
||||
if (child != null)
|
||||
|
@@ -29,10 +29,12 @@ package org.alfresco.module.org_alfresco_module_rm.test.util;
|
||||
|
||||
import static java.util.Collections.emptyMap;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.nullable;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@@ -179,19 +181,19 @@ public abstract class BaseWebScriptUnitTest extends BaseUnitTest
|
||||
org.springframework.extensions.webscripts.Runtime mockedRuntime = mock(org.springframework.extensions.webscripts.Runtime.class);
|
||||
|
||||
WebScriptRequest mockedRequest = mock(WebScriptRequest.class);
|
||||
doReturn(match).when(mockedRequest).getServiceMatch();
|
||||
doReturn(mockedRuntime).when(mockedRequest).getRuntime();
|
||||
lenient().doReturn(match).when(mockedRequest).getServiceMatch();
|
||||
lenient().doReturn(mockedRuntime).when(mockedRequest).getRuntime();
|
||||
|
||||
if (content != null && !content.isEmpty())
|
||||
{
|
||||
Content mockedContent = mock(Content.class);
|
||||
doReturn(content).when(mockedContent).getContent();
|
||||
doReturn(mockedContent).when(mockedRequest).getContent();
|
||||
lenient().doReturn(content).when(mockedContent).getContent();
|
||||
lenient().doReturn(mockedContent).when(mockedRequest).getContent();
|
||||
}
|
||||
|
||||
String [] paramNames = (String[])parameters.keySet().toArray(new String[parameters.size()]);
|
||||
doReturn(paramNames).when(mockedRequest).getParameterNames();
|
||||
doAnswer(new Answer()
|
||||
lenient().doReturn(paramNames).when(mockedRequest).getParameterNames();
|
||||
lenient().doAnswer(new Answer()
|
||||
{
|
||||
@Override
|
||||
public Object answer(InvocationOnMock invocation) throws Throwable
|
||||
@@ -201,9 +203,9 @@ public abstract class BaseWebScriptUnitTest extends BaseUnitTest
|
||||
}
|
||||
|
||||
}).when(mockedRequest).getParameter(anyString());
|
||||
|
||||
doReturn(new String[0]).when(mockedRequest).getHeaderNames();
|
||||
doReturn("json").when(mockedRequest).getFormat();
|
||||
|
||||
lenient().doReturn(new String[0]).when(mockedRequest).getHeaderNames();
|
||||
lenient().doReturn("json").when(mockedRequest).getFormat();
|
||||
|
||||
return mockedRequest;
|
||||
}
|
||||
@@ -217,7 +219,7 @@ public abstract class BaseWebScriptUnitTest extends BaseUnitTest
|
||||
{
|
||||
WebScriptResponse mockedResponse = mock(WebScriptResponse.class);
|
||||
StringWriter writer = new StringWriter();
|
||||
doReturn(writer).when(mockedResponse).getWriter();
|
||||
lenient().doReturn(writer).when(mockedResponse).getWriter();
|
||||
return mockedResponse;
|
||||
}
|
||||
|
||||
@@ -230,13 +232,13 @@ public abstract class BaseWebScriptUnitTest extends BaseUnitTest
|
||||
protected Container getMockedContainer(String template) throws Exception
|
||||
{
|
||||
FormatRegistry mockedFormatRegistry = mock(FormatRegistry.class);
|
||||
doReturn("application/json").when(mockedFormatRegistry).getMimeType(anyString(), anyString());
|
||||
lenient().doReturn("application/json").when(mockedFormatRegistry).getMimeType(nullable(String.class), nullable(String.class));
|
||||
|
||||
ScriptProcessorRegistry mockedScriptProcessorRegistry = mock(ScriptProcessorRegistry.class);
|
||||
doReturn(null).when(mockedScriptProcessorRegistry).findValidScriptPath(anyString());
|
||||
lenient().doReturn(null).when(mockedScriptProcessorRegistry).findValidScriptPath(anyString());
|
||||
|
||||
TemplateProcessorRegistry mockedTemplateProcessorRegistry = mock(TemplateProcessorRegistry.class);
|
||||
doReturn(template).when(mockedTemplateProcessorRegistry).findValidTemplatePath(anyString());
|
||||
lenient().doReturn(template).when(mockedTemplateProcessorRegistry).findValidTemplatePath(anyString());
|
||||
|
||||
FTLTemplateProcessor ftlTemplateProcessor = new FTLTemplateProcessor()
|
||||
{
|
||||
@@ -248,25 +250,25 @@ public abstract class BaseWebScriptUnitTest extends BaseUnitTest
|
||||
};
|
||||
ftlTemplateProcessor.init();
|
||||
|
||||
doReturn(ftlTemplateProcessor).when(mockedTemplateProcessorRegistry).getTemplateProcessor(anyString());
|
||||
lenient().doReturn(ftlTemplateProcessor).when(mockedTemplateProcessorRegistry).getTemplateProcessor(anyString());
|
||||
|
||||
Container mockedContainer = mock(Container.class);
|
||||
doReturn(mockedFormatRegistry).when(mockedContainer).getFormatRegistry();
|
||||
doReturn(mockedScriptProcessorRegistry).when(mockedContainer).getScriptProcessorRegistry();
|
||||
doReturn(mockedTemplateProcessorRegistry).when(mockedContainer).getTemplateProcessorRegistry();
|
||||
lenient().doReturn(mockedFormatRegistry).when(mockedContainer).getFormatRegistry();
|
||||
lenient().doReturn(mockedScriptProcessorRegistry).when(mockedContainer).getScriptProcessorRegistry();
|
||||
lenient().doReturn(mockedTemplateProcessorRegistry).when(mockedContainer).getTemplateProcessorRegistry();
|
||||
|
||||
Map<String, Object> containerTemplateParameters = new HashMap<>(5);
|
||||
containerTemplateParameters.put("jsonUtils", new JSONUtils());
|
||||
containerTemplateParameters.put("people", getMockedPeopleObject());
|
||||
doReturn(containerTemplateParameters).when(mockedContainer).getTemplateParameters();
|
||||
lenient().doReturn(containerTemplateParameters).when(mockedContainer).getTemplateParameters();
|
||||
|
||||
SearchPath mockedSearchPath = mock(SearchPath.class);
|
||||
doReturn(false).when(mockedSearchPath).hasDocument(anyString());
|
||||
doReturn(mockedSearchPath).when(mockedContainer).getSearchPath();
|
||||
lenient().doReturn(false).when(mockedSearchPath).hasDocument(anyString());
|
||||
lenient().doReturn(mockedSearchPath).when(mockedContainer).getSearchPath();
|
||||
|
||||
// setup description
|
||||
Description mockDescription = mock(Description.class);
|
||||
doReturn(mock(RequiredCache.class)).when(mockDescription).getRequiredCache();
|
||||
lenient().doReturn(mock(RequiredCache.class)).when(mockDescription).getRequiredCache();
|
||||
|
||||
return mockedContainer;
|
||||
}
|
||||
|
@@ -27,11 +27,10 @@
|
||||
|
||||
package org.alfresco.module.org_alfresco_module_rm.test.util;
|
||||
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.mockito.Mockito.reset;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.alfresco.module.org_alfresco_module_rm.util.AuthenticationUtil;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
||||
@@ -74,7 +73,7 @@ public class MockAuthenticationUtilHelper
|
||||
reset(mockAuthenticationUtil);
|
||||
|
||||
// just do the work
|
||||
doAnswer(new Answer<Object>()
|
||||
lenient().doAnswer(new Answer<Object>()
|
||||
{
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Override
|
||||
@@ -87,7 +86,7 @@ public class MockAuthenticationUtilHelper
|
||||
}).when(mockAuthenticationUtil).<Object> runAsSystem(any(RunAsWork.class));
|
||||
|
||||
// just do the work
|
||||
doAnswer(new Answer<Object>()
|
||||
lenient().doAnswer(new Answer<Object>()
|
||||
{
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Override
|
||||
@@ -99,10 +98,10 @@ public class MockAuthenticationUtilHelper
|
||||
|
||||
}).when(mockAuthenticationUtil).<Object> runAs(any(RunAsWork.class), anyString());
|
||||
|
||||
when(mockAuthenticationUtil.getAdminUserName()).thenReturn(ADMIN_USER);
|
||||
when(mockAuthenticationUtil.getFullyAuthenticatedUser()).thenReturn(fullyAuthenticatedUser);
|
||||
when(mockAuthenticationUtil.getRunAsUser()).thenReturn(fullyAuthenticatedUser);
|
||||
when(mockAuthenticationUtil.getSystemUserName()).thenReturn(SYSTEM_USER);
|
||||
when(mockAuthenticationUtil.getGuestUserName()).thenReturn(GUEST_USER);
|
||||
lenient().when(mockAuthenticationUtil.getAdminUserName()).thenReturn(ADMIN_USER);
|
||||
lenient().when(mockAuthenticationUtil.getFullyAuthenticatedUser()).thenReturn(fullyAuthenticatedUser);
|
||||
lenient().when(mockAuthenticationUtil.getRunAsUser()).thenReturn(fullyAuthenticatedUser);
|
||||
lenient().when(mockAuthenticationUtil.getSystemUserName()).thenReturn(SYSTEM_USER);
|
||||
lenient().when(mockAuthenticationUtil.getGuestUserName()).thenReturn(GUEST_USER);
|
||||
}
|
||||
}
|
||||
|
@@ -87,6 +87,7 @@ public class ContentBinDuplicationUtilityUnitTest
|
||||
public void setUp()
|
||||
{
|
||||
MockitoAnnotations.initMocks(this);
|
||||
contentBinDuplicationUtility.setNodeService(mockNodeService);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -29,10 +29,11 @@ package org.alfresco.module.org_alfresco_module_rm.version;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyMap;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyMap;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.nullable;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
@@ -52,7 +53,6 @@ import org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest;
|
||||
import org.alfresco.repo.version.Version2Model;
|
||||
import org.alfresco.repo.version.VersionModel;
|
||||
import org.alfresco.repo.version.common.VersionImpl;
|
||||
import org.alfresco.service.cmr.model.FileInfo;
|
||||
import org.alfresco.service.cmr.repository.ContentReader;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
@@ -61,9 +61,11 @@ import org.alfresco.service.cmr.version.VersionType;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Spy;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
/**
|
||||
* Recordable version service implementation unit test.
|
||||
@@ -71,6 +73,7 @@ import org.mockito.Spy;
|
||||
* @author Roy Wetherall
|
||||
* @since 2.3
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class RecordableVersionServiceImplUnitTest extends BaseUnitTest
|
||||
{
|
||||
/** versioned content name */
|
||||
@@ -108,34 +111,23 @@ public class RecordableVersionServiceImplUnitTest extends BaseUnitTest
|
||||
recordableVersionService.initialise();
|
||||
|
||||
doReturn(generateChildAssociationRef(null, generateNodeRef(Version2Model.TYPE_QNAME_VERSION_HISTORY)))
|
||||
.when(mockedDbNodeService).createNode(any(NodeRef.class),
|
||||
any(QName.class),
|
||||
any(QName.class),
|
||||
.when(mockedDbNodeService).createNode(nullable(NodeRef.class),
|
||||
nullable(QName.class),
|
||||
nullable(QName.class),
|
||||
eq(Version2Model.TYPE_QNAME_VERSION_HISTORY),
|
||||
anyMap());
|
||||
doReturn(generateChildAssociationRef(null, generateNodeRef(TYPE_CONTENT)))
|
||||
.when(mockedDbNodeService).createNode(any(NodeRef.class),
|
||||
any(QName.class),
|
||||
any(QName.class),
|
||||
eq(TYPE_CONTENT),
|
||||
anyMap());
|
||||
nullable(Map.class));
|
||||
|
||||
doReturn(filePlan).when(mockedFilePlanService).getFilePlanBySiteId(FilePlanService.DEFAULT_RM_SITE_ID);
|
||||
doReturn(unfiledRecordContainer).when(mockedFilePlanService).getUnfiledContainer(any(NodeRef.class));
|
||||
|
||||
record = generateCmContent(CONTENT_NAME);
|
||||
FileInfo mockedFileInfo = mock(FileInfo.class);
|
||||
doReturn(record).when(mockedFileInfo).getNodeRef();
|
||||
doReturn(mockedFileInfo).when(mockedFileFolderService).copy(any(NodeRef.class),
|
||||
any(NodeRef.class),
|
||||
any(String.class));
|
||||
version = generateNodeRef(TYPE_CONTENT);
|
||||
doReturn(generateChildAssociationRef(null, version)).when(mockedDbNodeService).createNode(
|
||||
any(NodeRef.class),
|
||||
nullable(NodeRef.class),
|
||||
eq(Version2Model.CHILD_QNAME_VERSIONS),
|
||||
any(QName.class),
|
||||
nullable(QName.class),
|
||||
eq(TYPE_CONTENT),
|
||||
anyMap());
|
||||
nullable(Map.class));
|
||||
recordableVersionService.setDbNodeService(mockedDbNodeService);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -167,7 +159,6 @@ public class RecordableVersionServiceImplUnitTest extends BaseUnitTest
|
||||
{
|
||||
// setup given conditions
|
||||
doReturn(false).when(mockedNodeService).hasAspect(nodeRef, RecordableVersionModel.ASPECT_VERSIONABLE);
|
||||
doReturn(null).when(mockedNodeService).getProperty(nodeRef, RecordableVersionModel.PROP_RECORDABLE_VERSION_POLICY);
|
||||
versionProperties.put(VersionModel.PROP_VERSION_TYPE, VersionType.MINOR);
|
||||
|
||||
// when version is created
|
||||
@@ -357,7 +348,6 @@ public class RecordableVersionServiceImplUnitTest extends BaseUnitTest
|
||||
public void filePlanSpecifiedNoPolicy() throws Exception
|
||||
{
|
||||
// setup given conditions
|
||||
doReturn(true).when(mockedNodeService).hasAspect(nodeRef, RecordableVersionModel.ASPECT_VERSIONABLE);
|
||||
versionProperties.put(VersionModel.PROP_VERSION_TYPE, VersionType.MAJOR);
|
||||
versionProperties.put(RecordableVersionServiceImpl.KEY_RECORDABLE_VERSION, true);
|
||||
|
||||
@@ -376,7 +366,6 @@ public class RecordableVersionServiceImplUnitTest extends BaseUnitTest
|
||||
public void adHocRecordedVersionNoPolicy() throws Exception
|
||||
{
|
||||
// setup given conditions
|
||||
doReturn(true).when(mockedNodeService).hasAspect(nodeRef, RecordableVersionModel.ASPECT_VERSIONABLE);
|
||||
versionProperties.put(VersionModel.PROP_VERSION_TYPE, VersionType.MAJOR);
|
||||
versionProperties.put(RecordableVersionServiceImpl.KEY_RECORDABLE_VERSION, true);
|
||||
|
||||
@@ -391,8 +380,6 @@ public class RecordableVersionServiceImplUnitTest extends BaseUnitTest
|
||||
public void adHocRecordedVersionOverridePolicy() throws Exception
|
||||
{
|
||||
// setup given conditions
|
||||
doReturn(true).when(mockedNodeService).hasAspect(nodeRef, RecordableVersionModel.ASPECT_VERSIONABLE);
|
||||
doReturn(RecordableVersionPolicy.MAJOR_ONLY.toString()).when(mockedNodeService).getProperty(nodeRef, RecordableVersionModel.PROP_RECORDABLE_VERSION_POLICY);
|
||||
versionProperties.put(VersionModel.PROP_VERSION_TYPE, VersionType.MINOR);
|
||||
versionProperties.put(RecordableVersionServiceImpl.KEY_RECORDABLE_VERSION, true);
|
||||
|
||||
@@ -461,16 +448,15 @@ public class RecordableVersionServiceImplUnitTest extends BaseUnitTest
|
||||
// latest version is not recorded
|
||||
Version mockedVersion = mock(VersionImpl.class);
|
||||
NodeRef versionNodeRef = generateNodeRef();
|
||||
doReturn(Collections.emptyMap()).when(mockedVersion).getVersionProperties();
|
||||
doReturn(true).when(mockedNodeService).hasAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE);
|
||||
|
||||
// version history
|
||||
NodeRef versionHistoryNodeRef = generateNodeRef();
|
||||
doReturn(versionHistoryNodeRef).when(mockedDbNodeService).getChildByName(any(NodeRef.class), eq(Version2Model.CHILD_QNAME_VERSION_HISTORIES), any(String.class));
|
||||
doReturn(versionHistoryNodeRef).when(mockedDbNodeService).getChildByName(nullable(NodeRef.class), eq(Version2Model.CHILD_QNAME_VERSION_HISTORIES), nullable(String.class));
|
||||
|
||||
// version number
|
||||
doReturn(mockedVersion).when(recordableVersionService).getCurrentVersion(nodeRef);
|
||||
doReturn(versionNodeRef).when(recordableVersionService).convertNodeRef(any(NodeRef.class));
|
||||
doReturn(versionNodeRef).when(recordableVersionService).convertNodeRef(nullable(NodeRef.class));
|
||||
makePrimaryParentOf(versionNodeRef, versionHistoryNodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "something-0"), mockedDbNodeService);
|
||||
|
||||
// created version
|
||||
@@ -478,36 +464,36 @@ public class RecordableVersionServiceImplUnitTest extends BaseUnitTest
|
||||
doReturn(generateChildAssociationRef(versionHistoryNodeRef, newVersionNodeRef)).when(mockedDbNodeService).createNode(
|
||||
eq(versionHistoryNodeRef),
|
||||
eq(Version2Model.CHILD_QNAME_VERSIONS),
|
||||
any(QName.class),
|
||||
any(QName.class),
|
||||
any(Map.class));
|
||||
nullable(QName.class),
|
||||
nullable(QName.class),
|
||||
nullable(Map.class));
|
||||
|
||||
// created record
|
||||
NodeRef newRecordNodeRef = generateNodeRef();
|
||||
doReturn(newRecordNodeRef).when(mockedRecordService).createRecordFromContent(
|
||||
eq(filePlan),
|
||||
any(String.class),
|
||||
any(QName.class),
|
||||
any(Map.class),
|
||||
any(ContentReader.class));
|
||||
eq(filePlan),
|
||||
nullable(String.class),
|
||||
nullable(QName.class),
|
||||
nullable(Map.class),
|
||||
nullable(ContentReader.class));
|
||||
|
||||
// create record from version
|
||||
recordableVersionService.createRecordFromLatestVersion(filePlan, nodeRef);
|
||||
|
||||
// verify that the version is converted to a recorded version
|
||||
verify(mockedRecordService, times(1)).createRecordFromContent(
|
||||
eq(filePlan),
|
||||
any(String.class),
|
||||
any(QName.class),
|
||||
any(Map.class),
|
||||
any(ContentReader.class));
|
||||
eq(filePlan),
|
||||
nullable(String.class),
|
||||
nullable(QName.class),
|
||||
any(Map.class),
|
||||
nullable(ContentReader.class));
|
||||
verify(mockedDbNodeService, times(1)).deleteNode(any(NodeRef.class));
|
||||
verify(mockedDbNodeService, times(1)).createNode(
|
||||
eq(versionHistoryNodeRef),
|
||||
eq(Version2Model.CHILD_QNAME_VERSIONS),
|
||||
any(QName.class),
|
||||
any(QName.class),
|
||||
any(Map.class));
|
||||
nullable(QName.class),
|
||||
nullable(QName.class),
|
||||
nullable(Map.class));
|
||||
verify(mockedNodeService, times(1)).addAspect(eq(newVersionNodeRef), eq(Version2Model.ASPECT_VERSION), any(Map.class));
|
||||
verify(mockedNodeService, times(1)).addAspect(
|
||||
newVersionNodeRef,
|
||||
@@ -605,20 +591,13 @@ public class RecordableVersionServiceImplUnitTest extends BaseUnitTest
|
||||
// set up version
|
||||
Version mockedVersion = mock(VersionImpl.class);
|
||||
NodeRef versionNodeRef = generateNodeRef();
|
||||
NodeRef versionRecordNodeRef = generateNodeRef();
|
||||
when(mockedVersion.getFrozenStateNodeRef())
|
||||
.thenReturn(versionNodeRef);
|
||||
when(mockedDbNodeService.exists(versionRecordNodeRef))
|
||||
.thenReturn(true);
|
||||
|
||||
|
||||
// indicate that the version doesn't have the aspect
|
||||
when(mockedDbNodeService.hasAspect(versionNodeRef, RecordableVersionModel.ASPECT_RECORDED_VERSION))
|
||||
.thenReturn(true);
|
||||
|
||||
// indicate that the associated version record exists
|
||||
when(mockedDbNodeService.getProperty(versionNodeRef, RecordableVersionModel.PROP_RECORD_NODE_REF))
|
||||
.thenReturn(versionRecordNodeRef);
|
||||
|
||||
// mark as destroyed
|
||||
recordableVersionService.destroyRecordedVersion(mockedVersion);
|
||||
|
||||
@@ -643,20 +622,13 @@ public class RecordableVersionServiceImplUnitTest extends BaseUnitTest
|
||||
// set up version
|
||||
Version mockedVersion = mock(VersionImpl.class);
|
||||
NodeRef versionNodeRef = generateNodeRef();
|
||||
NodeRef versionRecordNodeRef = generateNodeRef();
|
||||
when(mockedVersion.getFrozenStateNodeRef())
|
||||
.thenReturn(versionNodeRef);
|
||||
when(mockedDbNodeService.exists(versionRecordNodeRef))
|
||||
.thenReturn(false);
|
||||
|
||||
|
||||
// indicate that the version doesn't have the aspect
|
||||
when(mockedDbNodeService.hasAspect(versionNodeRef, RecordableVersionModel.ASPECT_RECORDED_VERSION))
|
||||
.thenReturn(true);
|
||||
|
||||
// indicate that the associated version record exists
|
||||
when(mockedDbNodeService.getProperty(versionNodeRef, RecordableVersionModel.PROP_RECORD_NODE_REF))
|
||||
.thenReturn(versionRecordNodeRef);
|
||||
|
||||
// mark as destroyed
|
||||
recordableVersionService.destroyRecordedVersion(mockedVersion);
|
||||
|
||||
|
@@ -33,10 +33,11 @@ import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyBoolean;
|
||||
import static org.mockito.Matchers.anyLong;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.nullable;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
@@ -562,7 +563,7 @@ public class DynamicAuthoritiesGetUnitTest extends BaseWebScriptUnitTest impleme
|
||||
executeWebScript(parameters);
|
||||
|
||||
verify(contentStreamer, times(1)).streamContent(any(WebScriptRequest.class), any(WebScriptResponse.class),
|
||||
csvFileCaptor.capture(), any(Long.class), any(Boolean.class), any(String.class), any(Map.class));
|
||||
csvFileCaptor.capture(), nullable(Long.class), any(Boolean.class), any(String.class), any(Map.class));
|
||||
|
||||
File fileForDownload = csvFileCaptor.getValue();
|
||||
assertNotNull(fileForDownload);
|
||||
|
@@ -28,8 +28,9 @@
|
||||
package org.alfresco.rm.rest.api.impl;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.nullable;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
@@ -41,7 +42,6 @@ import org.alfresco.module.org_alfresco_module_rm.dod5015.DOD5015Model;
|
||||
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
|
||||
import org.alfresco.module.org_alfresco_module_rm.test.util.AlfMock;
|
||||
import org.alfresco.module.org_alfresco_module_rm.test.util.BaseUnitTest;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.rest.api.impl.SiteImportPackageHandler;
|
||||
import org.alfresco.rest.api.model.Site;
|
||||
import org.alfresco.rest.api.model.SiteUpdate;
|
||||
@@ -59,10 +59,11 @@ import org.alfresco.service.cmr.view.Location;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
/**
|
||||
* Unit Test class for RMSitesImpl.
|
||||
@@ -71,6 +72,7 @@ import org.mockito.MockitoAnnotations;
|
||||
* @since 2.6
|
||||
*
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class RMSitesImplUnitTest extends BaseUnitTest
|
||||
{
|
||||
private static final String RM_SITE_TITLE_AFTER_UPDATE = "Updated Title";
|
||||
@@ -86,8 +88,6 @@ public class RMSitesImplUnitTest extends BaseUnitTest
|
||||
@Mock
|
||||
private SiteService mockedSiteService;
|
||||
@Mock
|
||||
AuthenticationUtil mockAuthenticationUtil;
|
||||
@Mock
|
||||
private ImporterService mockedImporterService;
|
||||
@Mock
|
||||
private FavouritesService mockedFavouritesService;
|
||||
@@ -95,7 +95,6 @@ public class RMSitesImplUnitTest extends BaseUnitTest
|
||||
@Before
|
||||
public void before()
|
||||
{
|
||||
MockitoAnnotations.initMocks(this);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -138,7 +137,7 @@ public class RMSitesImplUnitTest extends BaseUnitTest
|
||||
|
||||
verify(mockedImporterService, times(1)).importView(any(SiteImportPackageHandler.class), any(Location.class), any(ImporterBinding.class), eq(null));
|
||||
verify(mockedSiteService, times(1)).createContainer(RM_SITE_ID, SiteService.DOCUMENT_LIBRARY, ContentModel.TYPE_FOLDER, null);
|
||||
verify(mockedFavouritesService, times(1)).addFavourite(any(String.class), any(NodeRef.class));
|
||||
verify(mockedFavouritesService, times(1)).addFavourite(nullable(String.class), any(NodeRef.class));
|
||||
|
||||
//verify returned values for RM site are the right ones
|
||||
assertEquals(RMSiteCompliance.STANDARD, createdRMSite.getCompliance());
|
||||
@@ -191,7 +190,7 @@ public class RMSitesImplUnitTest extends BaseUnitTest
|
||||
|
||||
verify(mockedImporterService, times(1)).importView(any(SiteImportPackageHandler.class), any(Location.class), any(ImporterBinding.class), eq(null));
|
||||
verify(mockedSiteService, times(1)).createContainer(RM_SITE_ID, SiteService.DOCUMENT_LIBRARY, ContentModel.TYPE_FOLDER, null);
|
||||
verify(mockedFavouritesService, times(1)).addFavourite(any(String.class), any(NodeRef.class));
|
||||
verify(mockedFavouritesService, times(1)).addFavourite(nullable(String.class), any(NodeRef.class));
|
||||
|
||||
//verify returned values for RM site are the right ones
|
||||
assertEquals(RMSiteCompliance.DOD5015, createdRMSite.getCompliance());
|
||||
@@ -253,13 +252,12 @@ public class RMSitesImplUnitTest extends BaseUnitTest
|
||||
when(mockedNodeService.getType(siteNodeRef)).thenReturn(RecordsManagementModel.TYPE_RM_SITE);
|
||||
|
||||
when(mockedSiteService.getSite(siteId)).thenReturn(mockedSiteInfo);
|
||||
when(mockedSiteService.getMembersRole(eq(siteId), any(String.class))).thenReturn(RM_SITE_MANAGER_ROLE);
|
||||
when(mockedSiteService.getMembersRole(eq(siteId), nullable(String.class))).thenReturn(RM_SITE_MANAGER_ROLE);
|
||||
|
||||
//mock UpdateSite
|
||||
SiteUpdate mockedSiteUpdate= mock(SiteUpdate.class);
|
||||
when(mockedSiteUpdate.getDescription()).thenReturn(RM_SITE_DESCRIPTION_AFTER_UPDATE);
|
||||
when(mockedSiteUpdate.getTitle()).thenReturn(RM_SITE_TITLE_AFTER_UPDATE);
|
||||
when(mockedSiteUpdate.getVisibility()).thenReturn(null);
|
||||
when(mockedSiteUpdate.wasSet(Site.TITLE)).thenReturn(true);
|
||||
when(mockedSiteUpdate.wasSet(Site.DESCRIPTION)).thenReturn(true);
|
||||
|
||||
@@ -309,7 +307,7 @@ public class RMSitesImplUnitTest extends BaseUnitTest
|
||||
when(mockedNodeService.getType(siteNodeRef)).thenReturn(RecordsManagementModel.TYPE_RM_SITE);
|
||||
|
||||
when(mockedSiteService.getSite(siteId)).thenReturn(mockedSiteInfo);
|
||||
when(mockedSiteService.getMembersRole(eq(siteId), any(String.class))).thenReturn(RM_SITE_MANAGER_ROLE);
|
||||
when(mockedSiteService.getMembersRole(eq(siteId), nullable(String.class))).thenReturn(RM_SITE_MANAGER_ROLE);
|
||||
|
||||
//STANDARD compliance
|
||||
RMSite rmSite = rmSitesImpl.getRMSite(siteId);
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-governance-services-community-repo-parent</artifactId>
|
||||
<version>14.15-SNAPSHOT</version>
|
||||
<version>14.52</version>
|
||||
</parent>
|
||||
|
||||
<build>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>14.15-SNAPSHOT</version>
|
||||
<version>14.52</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
|
@@ -8,7 +8,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-amps</artifactId>
|
||||
<version>14.15-SNAPSHOT</version>
|
||||
<version>14.52</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
|
@@ -1,5 +1,6 @@
|
||||
const THUMBNAIL_NAME = "doclib",
|
||||
TYPE_SITES = "st:sites",
|
||||
SITES_PATH = "Sites/",
|
||||
PREF_DOCUMENT_FAVOURITES = "org.alfresco.share.documents.favourites",
|
||||
PREF_FOLDER_FAVOURITES = "org.alfresco.share.folders.favourites",
|
||||
LIKES_SCHEME = "likesRatingScheme";
|
||||
@@ -278,8 +279,39 @@ var ParseArgs =
|
||||
pathNode = path.length > 0 ? rootNode.childByNamePath(path) : (pathNode || rootNode);
|
||||
if (pathNode === null)
|
||||
{
|
||||
status.setCode(status.STATUS_NOT_FOUND, "Path not found: '" + path + "'");
|
||||
return null;
|
||||
// Path was not found in rootNode so a search attempt will be performed in companyHome
|
||||
pathNode = path.length > 0 ? companyhome.childByNamePath(path) : null;
|
||||
|
||||
// At this point, if path hasn't been found yet, a site search will be executed (if path first element is a site)
|
||||
if (pathNode === null)
|
||||
{
|
||||
if (path && path.length > 0)
|
||||
{
|
||||
var siteId;
|
||||
var idx = path.startsWith("/") ? 1 : 0;
|
||||
|
||||
if (idx >= 0)
|
||||
{
|
||||
siteId = path.split("/")[idx];
|
||||
if (siteId)
|
||||
{
|
||||
var siteNode = siteService.getSiteInfo(siteId);
|
||||
if (siteNode !== null)
|
||||
{
|
||||
path = SITES_PATH + path;
|
||||
pathNode = companyhome.childByNamePath(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If path node is still null, it wasn't possible to find it and STATUS_NOT_FOUND will be returned
|
||||
if (pathNode === null)
|
||||
{
|
||||
status.setCode(status.STATUS_NOT_FOUND, "Path not found: '" + path + "'");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Parent location parameter adjustment
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>14.15-SNAPSHOT</version>
|
||||
<version>14.52</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>14.15-SNAPSHOT</version>
|
||||
<version>14.52</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
@@ -130,7 +130,7 @@
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.woodstox</groupId>
|
||||
<artifactId>woodstox-core</artifactId>
|
||||
<version>6.2.6</version>
|
||||
<version>6.2.7</version>
|
||||
</dependency>
|
||||
|
||||
<!-- the cxf libs were updated, see dependencyManagement section -->
|
||||
@@ -230,13 +230,9 @@
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.tika</groupId>
|
||||
<artifactId>tika-parsers</artifactId>
|
||||
<artifactId>tika-parsers-standard-package</artifactId>
|
||||
<version>${dependency.tika.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.tdunning</groupId>
|
||||
<artifactId>json</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcprov-jdk15on</artifactId>
|
||||
@@ -245,39 +241,6 @@
|
||||
<groupId>asm</groupId>
|
||||
<artifactId>asm</artifactId>
|
||||
</exclusion>
|
||||
<!-- Duplicates classes from jakarta.jws:jakarta.jws-api -->
|
||||
<exclusion>
|
||||
<groupId>org.apache.geronimo.specs</groupId>
|
||||
<artifactId>geronimo-ws-metadata_2.0_spec</artifactId>
|
||||
</exclusion>
|
||||
<!-- Duplicates classes from jakarta.transaction:jakarta.transaction-api -->
|
||||
<exclusion>
|
||||
<groupId>org.apache.geronimo.specs</groupId>
|
||||
<artifactId>geronimo-jta_1.1_spec</artifactId>
|
||||
</exclusion>
|
||||
<!-- Duplicates classes from jakarta.annotation:jakarta.annotation-api -->
|
||||
<exclusion>
|
||||
<groupId>javax.annotation</groupId>
|
||||
<artifactId>javax.annotation-api</artifactId>
|
||||
</exclusion>
|
||||
<!-- Duplicates classes from com.sun.activation:jakarta.activation -->
|
||||
<exclusion>
|
||||
<groupId>com.sun.activation</groupId>
|
||||
<artifactId>javax.activation</artifactId>
|
||||
</exclusion>
|
||||
<!-- Duplicates classes from jakarta -->
|
||||
<exclusion>
|
||||
<groupId>javax.xml.bind</groupId>
|
||||
<artifactId>jaxb-api</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>javax.activation</groupId>
|
||||
<artifactId>activation</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>javax.activation</groupId>
|
||||
<artifactId>javax.activation-api</artifactId>
|
||||
</exclusion>
|
||||
<!-- No longer needed -->
|
||||
<exclusion>
|
||||
<groupId>org.apache.pdfbox</groupId>
|
||||
@@ -287,18 +250,10 @@
|
||||
<groupId>org.apache.pdfbox</groupId>
|
||||
<artifactId>pdfbox-tools</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.apache.pdfbox</groupId>
|
||||
<artifactId>preflight</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.apache.pdfbox</groupId>
|
||||
<artifactId>jempbox</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.apache.pdfbox</groupId>
|
||||
<artifactId>xmpbox</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.apache.pdfbox</groupId>
|
||||
<artifactId>jbig2-imageio</artifactId>
|
||||
@@ -306,6 +261,19 @@
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Test dependencies -->
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
|
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Remote API
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2021 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco 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 Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
package org.alfresco.repo.content;
|
||||
|
||||
import org.alfresco.service.Experimental;
|
||||
|
||||
/**
|
||||
* Enumeration with values for archive-restore parameter keys.
|
||||
* Values of this enum should be used as keys when requesting for content restore from archive.
|
||||
* Subject to expand/change.
|
||||
*
|
||||
* @author mpichura
|
||||
*/
|
||||
@Experimental
|
||||
public enum ContentRestoreParams
|
||||
{
|
||||
/**
|
||||
* Restore expiry in days. Corresponding value should be integer.
|
||||
*/
|
||||
EXPIRY_DAYS,
|
||||
/**
|
||||
* Priority for restore from archive. Corresponding value should one of Standard/High
|
||||
*/
|
||||
RESTORE_PRIORITY
|
||||
}
|
@@ -26,6 +26,7 @@
|
||||
package org.alfresco.repo.content;
|
||||
|
||||
import org.alfresco.api.AlfrescoPublicApi;
|
||||
import org.alfresco.service.Experimental;
|
||||
import org.alfresco.service.cmr.repository.ContentAccessor;
|
||||
import org.alfresco.service.cmr.repository.ContentIOException;
|
||||
import org.alfresco.service.cmr.repository.ContentReader;
|
||||
@@ -33,6 +34,10 @@ import org.alfresco.service.cmr.repository.ContentStreamListener;
|
||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
import org.alfresco.service.cmr.repository.DirectAccessUrl;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
* Provides low-level retrieval of content
|
||||
@@ -324,4 +329,57 @@ public interface ContentStore
|
||||
throw new UnsupportedOperationException(
|
||||
"Retrieving direct access URLs is not supported by this content store.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a key-value (String-String) collection of storage headers/properties with their respective values.
|
||||
* A particular Cloud Connector will fill in that data with Cloud Storage Provider generic data.
|
||||
* Map may be also filled in with entries consisting of pre-defined Alfresco keys of {@code ObjectStorageProps} and their values.
|
||||
* If empty Map is returned - no connector is present or connector is not supporting retrieval of the properties
|
||||
* or cannot determine the properties.
|
||||
*
|
||||
* @param contentUrl the URL of the content for which the storage properties are to be retrieved.
|
||||
* @return Returns a key-value (String-String) collection of storage headers/properties with their respective values.
|
||||
*/
|
||||
@Experimental
|
||||
default Map<String, String> getStorageProperties(String contentUrl)
|
||||
{
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit a request to send content to archive (offline) state.
|
||||
* If no connector is present or connector is not supporting sending to archive, then {@link UnsupportedOperationException} will be returned.
|
||||
* Specific connector will decide which storage class/tier will be set for content.
|
||||
* This method is experimental and subject to changes.
|
||||
*
|
||||
* @param contentUrl the URL of the content which is to be archived.
|
||||
* @param archiveParams a map of String-Serializable parameters defining Storage Provider specific request parameters (can be empty).
|
||||
* @return true when request successful, false when unsuccessful.
|
||||
* @throws UnsupportedOperationException when store is unable to handle request.
|
||||
*/
|
||||
@Experimental
|
||||
default boolean requestSendContentToArchive(String contentUrl, Map<String, Serializable> archiveParams)
|
||||
{
|
||||
throw new UnsupportedOperationException("Request to archive content is not supported by this content store.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit a request to restore content from archive (offline) state.
|
||||
* If no connector is present or connector is not supporting restoring fom archive, then {@link UnsupportedOperationException} will be returned.
|
||||
* One of input parameters of this method is a map (String-Serializable) of Storage Provider specific input needed to perform proper restore.
|
||||
* Keys of this map should be restricted to {@code ContentRestoreParams} enumeration.
|
||||
* For AWS S3 map can indicating expiry days, Glacier restore tier.
|
||||
* For Azure Blob map can indicate rehydrate priority.
|
||||
* This method is experimental and subject to changes.
|
||||
*
|
||||
* @param contentUrl the URL of the content which is to be archived.
|
||||
* @param restoreParams a map of String-Serializable parameters defining Storage Provider specific request parameters (can be empty).
|
||||
* @return true when request successful, false when unsuccessful.
|
||||
* @throws UnsupportedOperationException when store is unable to handle request.
|
||||
*/
|
||||
@Experimental
|
||||
default boolean requestRestoreContentFromArchive(String contentUrl, Map<String, Serializable> restoreParams)
|
||||
{
|
||||
throw new UnsupportedOperationException("Request to restore content from archive is not supported by this content store.");
|
||||
}
|
||||
}
|
||||
|
@@ -2,7 +2,7 @@
|
||||
* #%L
|
||||
* Alfresco Data model classes
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2020 Alfresco Software Limited
|
||||
* Copyright (C) 2005 - 2021 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
@@ -42,6 +42,7 @@ import org.apache.tika.detect.DefaultDetector;
|
||||
import org.apache.tika.detect.Detector;
|
||||
import org.apache.tika.io.TikaInputStream;
|
||||
import org.apache.tika.metadata.Metadata;
|
||||
import org.apache.tika.metadata.TikaCoreProperties;
|
||||
import org.apache.tika.mime.MediaType;
|
||||
import org.quartz.CronExpression;
|
||||
import org.springframework.extensions.config.Config;
|
||||
@@ -192,6 +193,8 @@ public class MimetypeMap implements MimetypeService
|
||||
|
||||
public static final String MIMETYPE_IMAGE_DWT = "image/x-dwt";
|
||||
|
||||
public static final String MIMETYPE_IMAGE_ICNS = "image/icns";
|
||||
|
||||
public static final String MIMETYPE_APPLICATION_EPS = "application/eps";
|
||||
|
||||
public static final String MIMETYPE_APPLICATION_PS = "application/postscript";
|
||||
@@ -936,7 +939,8 @@ public class MimetypeMap implements MimetypeService
|
||||
Metadata metadata = new Metadata();
|
||||
if (filename != null)
|
||||
{
|
||||
metadata.add(Metadata.RESOURCE_NAME_KEY, filename);
|
||||
//"resourceName"
|
||||
metadata.add(TikaCoreProperties.RESOURCE_NAME_KEY, filename);
|
||||
}
|
||||
|
||||
InputStream inp = null;
|
||||
|
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Data model classes
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2021 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco 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 Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
package org.alfresco.repo.content;
|
||||
|
||||
import org.alfresco.service.Experimental;
|
||||
|
||||
/**
|
||||
* Enumeration with "header" values for Alfresco derived Storage Properties
|
||||
* Values of this enum should be used when adding Alfresco derived key-value pairs in Storage Properties map.
|
||||
* Subject to expand/change.
|
||||
*
|
||||
* @author mpichura
|
||||
*/
|
||||
@Experimental
|
||||
public enum ObjectStorageProps {
|
||||
/**
|
||||
* Object's content is archived and not immediately accessible.
|
||||
*/
|
||||
X_ALF_ARCHIVED("x-alf-archived"),
|
||||
/**
|
||||
* Object's content retrieval from archive is in progress
|
||||
*/
|
||||
X_ALF_ARCHIVE_RESTORE_IN_PROGRESS("x-alf-archive-restore-in-progress"),
|
||||
/**
|
||||
* Expiry date and time of object's content retrieved from archive.
|
||||
* Use YYYYMMDDThhmmssZ (ISO-8601) datetime format when using this value as key in Storage Properties map.
|
||||
*/
|
||||
X_ALF_ARCHIVE_RESTORE_EXPIRY("x-alf-archive-restore-expiry");
|
||||
|
||||
ObjectStorageProps(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
private final String value;
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Data model classes
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2021 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco 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 Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.service;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Annotation to mark a type/method/field as experimental.
|
||||
* <p>
|
||||
* If this annotation is present on an element it marks it as experimental and subject to change without further notice.
|
||||
* The element may even be deleted or renamed without any notice.
|
||||
* Experimental element may likely become a valid one (not experimental anymore) in future releases but there is no guarantee when
|
||||
* and if that happens.
|
||||
*
|
||||
* @author mpichura
|
||||
*/
|
||||
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.TYPE})
|
||||
@Retention(RetentionPolicy.CLASS)
|
||||
@Documented
|
||||
public @interface Experimental {
|
||||
/**
|
||||
* Further description that can optionally be added to clarify possible future changes of annotated object.
|
||||
*
|
||||
* @return a String, the default is an empty String.
|
||||
*/
|
||||
String description() default "";
|
||||
|
||||
}
|
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Data model classes
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2021 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco 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 Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.service.cmr.repository;
|
||||
|
||||
import org.alfresco.api.AlfrescoPublicApi;
|
||||
import org.alfresco.service.Experimental;
|
||||
|
||||
/**
|
||||
* Unable to access as content is in an Archived state.
|
||||
* Default status is <i>Precondition Failed<i> Client Error = 412
|
||||
*
|
||||
* @author David Edwards
|
||||
*/
|
||||
@Experimental
|
||||
@AlfrescoPublicApi
|
||||
public class ArchivedIOException extends ContentIOException
|
||||
{
|
||||
private static final long serialVersionUID = 3258135874596276087L;
|
||||
|
||||
public ArchivedIOException(String msg)
|
||||
{
|
||||
super(msg);
|
||||
}
|
||||
|
||||
public ArchivedIOException(String msg, Throwable cause)
|
||||
{
|
||||
super(msg, cause);
|
||||
}
|
||||
|
||||
}
|
@@ -611,6 +611,10 @@
|
||||
<mimetype mimetype="application/vnd.apple.numbers" display="Apple iWork Numbers">
|
||||
<extension>numbers</extension>
|
||||
</mimetype>
|
||||
<!-- Apple ICNS files -->
|
||||
<mimetype mimetype="image/icns" display="Apple Icon">
|
||||
<extension>icns</extension>
|
||||
</mimetype>
|
||||
|
||||
<!-- Markdown -->
|
||||
<mimetype mimetype="text/x-markdown" display="Markdown">
|
||||
|
@@ -94,7 +94,8 @@ public class MimetypeMapTest extends TestCase
|
||||
// other text forms
|
||||
assertEquals("text/csv", mimetypesByExtension.get("csv"));
|
||||
assertEquals("text/html", mimetypesByExtension.get("html"));
|
||||
|
||||
assertEquals("image/icns", mimetypesByExtension.get("icns"));
|
||||
|
||||
// JPEG
|
||||
assertEquals("jpg", extensionsByMimetype.get("image/jpeg"));
|
||||
assertEquals("image/jpeg", mimetypesByExtension.get("jpg"));
|
||||
|
@@ -2,7 +2,7 @@
|
||||
* #%L
|
||||
* Alfresco Data model classes
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
||||
* Copyright (C) 2005 - 2021 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
@@ -26,7 +26,6 @@
|
||||
package org.alfresco.repo.dictionary;
|
||||
|
||||
import static java.util.function.Function.identity;
|
||||
import static java.util.stream.Collectors.averagingDouble;
|
||||
import static java.util.stream.Collectors.toMap;
|
||||
|
||||
import static org.alfresco.repo.dictionary.M2ModelDiff.DIFF_CREATED;
|
||||
@@ -40,30 +39,13 @@ import static org.alfresco.repo.dictionary.M2ModelDiff.TYPE_PROPERTY;
|
||||
import static org.alfresco.repo.dictionary.M2ModelDiff.TYPE_TYPE;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.repo.tenant.SingleTServiceImpl;
|
||||
import org.alfresco.repo.tenant.TenantService;
|
||||
import org.alfresco.service.namespace.NamespaceException;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.util.DynamicallySizedThreadPoolExecutor;
|
||||
import org.alfresco.util.Pair;
|
||||
import org.alfresco.util.TraceableThreadFactory;
|
||||
import org.alfresco.util.cache.DefaultAsynchronouslyRefreshedCacheRegistry;
|
||||
import org.apache.commons.collections4.map.UnmodifiableMap;
|
||||
|
||||
public class DiffModelTest extends AbstractModelTest
|
||||
{
|
||||
|
112
mmt/pom.xml
Normal file
112
mmt/pom.xml
Normal file
@@ -0,0 +1,112 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>alfresco-mmt</artifactId>
|
||||
<name>Alfresco Module Management Tool</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>14.52</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-repository</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>de.schlichtherle.truezip</groupId>
|
||||
<artifactId>truezip-driver-zip</artifactId>
|
||||
<version>${dependency.truezip.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>de.schlichtherle.truezip</groupId>
|
||||
<artifactId>truezip-file</artifactId>
|
||||
<version>${dependency.truezip.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven</groupId>
|
||||
<artifactId>maven-artifact</artifactId>
|
||||
<version>${dependency.maven-artifact.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>make-mmt</id>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<transformers>
|
||||
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
||||
<manifestEntries>
|
||||
<Main-Class>org.alfresco.repo.module.tool.ModuleManagementTool</Main-Class>
|
||||
</manifestEntries>
|
||||
</transformer>
|
||||
</transformers>
|
||||
<artifactSet>
|
||||
<includes>
|
||||
<include>de.schlichtherle.truezip:*</include>
|
||||
<include>org.alfresco:alfresco-core</include>
|
||||
<include>org.alfresco:alfresco-repository</include>
|
||||
<include>org.apache.commons:commons-compress</include>
|
||||
<include>org.safehaus.jug:jug</include>
|
||||
<include>org.alfresco.surf:spring-surf-core</include>
|
||||
<include>org.tukaani:xz</include>
|
||||
<include>org.apache.maven:maven-artifact</include>
|
||||
</includes>
|
||||
</artifactSet>
|
||||
<filters>
|
||||
<filter>
|
||||
<artifact>org.alfresco:alfresco-core</artifact>
|
||||
<includes>
|
||||
<include>org/alfresco/error/AlfrescoRuntimeException.class</include>
|
||||
<include>org/alfresco/util/Pair.class</include>
|
||||
<include>org/alfresco/util/EqualsHelper.class</include>
|
||||
<include>org/alfresco/util/VersionNumber.class</include>
|
||||
</includes>
|
||||
</filter>
|
||||
<filter>
|
||||
<artifact>org.apache.maven:maven-artifact</artifact>
|
||||
<includes>
|
||||
<include>org/apache/maven/artifact/versioning/**/*.class</include>
|
||||
</includes>
|
||||
</filter>
|
||||
<filter>
|
||||
<artifact>org.alfresco:alfresco-repository</artifact>
|
||||
<includes>
|
||||
<include>org/alfresco/repo/module/tool/default-file-mapping.properties</include>
|
||||
<include>org/alfresco/repo/module/**/*.class</include>
|
||||
<include>org/alfresco/service/cmr/module/**/*.class</include>
|
||||
</includes>
|
||||
</filter>
|
||||
<filter>
|
||||
<artifact>org.alfresco.surf:spring-surf-core</artifact>
|
||||
<includes>
|
||||
<include>org/springframework/extensions/surf/util/I18NUtil.class</include>
|
||||
<include>org/springframework/extensions/surf/util/ISO8601DateFormat.class</include>
|
||||
<include>org/springframework/extensions/surf/exception/PlatformRuntimeException.class</include>
|
||||
</includes>
|
||||
</filter>
|
||||
<filter>
|
||||
<!-- Duplicated file in truezip-driver-file, need to filter this one -->
|
||||
<artifact>de.schlichtherle.truezip:truezip-driver-zip</artifact>
|
||||
<excludes>
|
||||
<exclude>META-INF/services/de.schlichtherle.truezip.fs.spi.FsDriverService</exclude>
|
||||
</excludes>
|
||||
</filter>
|
||||
</filters>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
165
mmt/src/main/resources/LICENSE
Normal file
165
mmt/src/main/resources/LICENSE
Normal file
@@ -0,0 +1,165 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
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.
|
@@ -9,6 +9,6 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-packaging</artifactId>
|
||||
<version>14.15-SNAPSHOT</version>
|
||||
<version>14.52</version>
|
||||
</parent>
|
||||
</project>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-packaging</artifactId>
|
||||
<version>14.15-SNAPSHOT</version>
|
||||
<version>14.52</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
@@ -71,6 +71,7 @@
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-mmt</artifactId>
|
||||
<type>jar</type>
|
||||
<version>${project.version}</version>
|
||||
<overWrite>false</overWrite>
|
||||
<outputDirectory>${project.build.directory}/alfresco-mmt</outputDirectory>
|
||||
</artifactItem>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>14.15-SNAPSHOT</version>
|
||||
<version>14.52</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
|
@@ -1,4 +1,4 @@
|
||||
TRANSFORMERS_TAG=2.5.3
|
||||
TRANSFORMERS_TAG=2.5.4
|
||||
SOLR6_TAG=2.0.2
|
||||
POSTGRES_TAG=13.3
|
||||
ACTIVEMQ_TAG=5.16.1
|
||||
|
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-packaging</artifactId>
|
||||
<version>14.15-SNAPSHOT</version>
|
||||
<version>14.52</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
|
@@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||
<version>14.15-SNAPSHOT</version>
|
||||
<version>14.52</version>
|
||||
</parent>
|
||||
|
||||
<developers>
|
||||
|
@@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||
<version>14.15-SNAPSHOT</version>
|
||||
<version>14.52</version>
|
||||
</parent>
|
||||
|
||||
<developers>
|
||||
|
@@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||
<version>14.15-SNAPSHOT</version>
|
||||
<version>14.52</version>
|
||||
</parent>
|
||||
|
||||
<developers>
|
||||
|
@@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||
<version>14.15-SNAPSHOT</version>
|
||||
<version>14.52</version>
|
||||
</parent>
|
||||
|
||||
<developers>
|
||||
|
@@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||
<version>14.15-SNAPSHOT</version>
|
||||
<version>14.52</version>
|
||||
</parent>
|
||||
|
||||
<developers>
|
||||
|
@@ -198,4 +198,15 @@ public class UnlockFileTests extends WebDavTest
|
||||
.then().unlock()
|
||||
.and().assertThat().hasStatus(HttpStatus.NO_CONTENT.value()).and().assertThat().isUnlocked();
|
||||
}
|
||||
|
||||
@TestRail(section={TestGroup.PROTOCOLS, TestGroup.WEBDAV}, executionType= ExecutionType.SANITY,
|
||||
description ="Checks no existent file is not locked (and status 404)")
|
||||
@Test(groups = {TestGroup.PROTOCOLS, TestGroup.WEBDAV, TestGroup.SANITY})
|
||||
public void checkLockStatusForNonExistentFile() throws Exception
|
||||
{
|
||||
testFile = FileModel.getRandomFileModel(FileType.TEXT_PLAIN, content);
|
||||
webDavProtocol.authenticateUser(dataUser.getAdminUser()).
|
||||
usingResource(testFile).
|
||||
assertThat().isUnlocked().assertThat().hasStatus(HttpStatus.NOT_FOUND.value());
|
||||
}
|
||||
}
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-packaging</artifactId>
|
||||
<version>14.15-SNAPSHOT</version>
|
||||
<version>14.52</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
|
@@ -2,7 +2,7 @@
|
||||
#%L
|
||||
Alfresco Repository WAR Community
|
||||
%%
|
||||
Copyright (C) 2005 - 2016 Alfresco Software Limited
|
||||
Copyright (C) 2005 - 2021 Alfresco Software Limited
|
||||
%%
|
||||
This file is part of the Alfresco software.
|
||||
If the software was purchased under a paid Alfresco license, the terms of
|
||||
@@ -35,15 +35,6 @@
|
||||
<%@ page import="org.alfresco.service.cmr.module.ModuleInstallState" %>
|
||||
<%@ page import="java.util.Calendar" %>
|
||||
|
||||
<!-- Enterprise index-jsp placeholder -->
|
||||
<%
|
||||
// route WebDAV requests
|
||||
if (request.getMethod().equalsIgnoreCase("PROPFIND") || request.getMethod().equalsIgnoreCase("OPTIONS"))
|
||||
{
|
||||
response.sendRedirect(request.getContextPath() + "/webdav/");
|
||||
}
|
||||
%>
|
||||
|
||||
<%
|
||||
WebApplicationContext context = WebApplicationContextUtils.getRequiredWebApplicationContext(session.getServletContext());
|
||||
SysAdminParams sysAdminParams = (SysAdminParams)context.getBean("sysAdminParams");
|
||||
|
47
pom.xml
47
pom.xml
@@ -2,7 +2,7 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>14.15-SNAPSHOT</version>
|
||||
<version>14.52</version>
|
||||
<packaging>pom</packaging>
|
||||
<name>Alfresco Community Repo Parent</name>
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
<module>data-model</module>
|
||||
<module>repository</module>
|
||||
<module>remote-api</module>
|
||||
<module>mmt</module>
|
||||
<module>packaging</module>
|
||||
<module>amps</module>
|
||||
</modules>
|
||||
@@ -43,7 +44,6 @@
|
||||
<dir.root>${project.build.directory}/alf_data</dir.root>
|
||||
|
||||
<dependency.alfresco-hb-data-sender.version>1.0.12</dependency.alfresco-hb-data-sender.version>
|
||||
<dependency.alfresco-mmt.version>6.0</dependency.alfresco-mmt.version>
|
||||
<dependency.alfresco-trashcan-cleaner.version>2.4.1</dependency.alfresco-trashcan-cleaner.version>
|
||||
<dependency.alfresco-jlan.version>7.1</dependency.alfresco-jlan.version>
|
||||
<dependency.alfresco-server-root.version>6.0.1</dependency.alfresco-server-root.version>
|
||||
@@ -51,20 +51,19 @@
|
||||
<dependency.alfresco-log-sanitizer.version>0.2</dependency.alfresco-log-sanitizer.version>
|
||||
<dependency.activiti-engine.version>5.23.0</dependency.activiti-engine.version>
|
||||
<dependency.activiti.version>5.23.0</dependency.activiti.version>
|
||||
<dependency.alfresco-transform-model.version>1.4.0</dependency.alfresco-transform-model.version>
|
||||
<dependency.alfresco-transform-model.version>1.4.3</dependency.alfresco-transform-model.version>
|
||||
<dependency.alfresco-greenmail.version>6.2</dependency.alfresco-greenmail.version>
|
||||
<dependency.acs-event-model.version>0.0.13</dependency.acs-event-model.version>
|
||||
|
||||
<dependency.spring.version>5.3.10</dependency.spring.version>
|
||||
<dependency.spring.version>5.3.13</dependency.spring.version>
|
||||
<dependency.antlr.version>3.5.2</dependency.antlr.version>
|
||||
<dependency.jackson.version>2.12.3</dependency.jackson.version>
|
||||
<dependency.jackson-databind.version>2.12.4</dependency.jackson-databind.version>
|
||||
<dependency.cxf.version>3.4.5</dependency.cxf.version>
|
||||
<dependency.opencmis.version>1.0.0</dependency.opencmis.version>
|
||||
<dependency.webscripts.version>8.24</dependency.webscripts.version>
|
||||
<dependency.bouncycastle.version>1.69</dependency.bouncycastle.version>
|
||||
<dependency.webscripts.version>8.26</dependency.webscripts.version>
|
||||
<dependency.bouncycastle.version>1.70</dependency.bouncycastle.version>
|
||||
<dependency.mockito-core.version>3.11.2</dependency.mockito-core.version>
|
||||
<dependency.mockito-all.version>1.10.19</dependency.mockito-all.version>
|
||||
<dependency.org-json.version>20210307</dependency.org-json.version>
|
||||
<dependency.commons-dbcp.version>1.4-DBCP330</dependency.commons-dbcp.version>
|
||||
<dependency.commons-io.version>2.11.0</dependency.commons-io.version>
|
||||
@@ -76,7 +75,7 @@
|
||||
<dependency.slf4j.version>1.7.32</dependency.slf4j.version>
|
||||
<dependency.gytheio.version>0.12</dependency.gytheio.version>
|
||||
<dependency.groovy.version>3.0.9</dependency.groovy.version>
|
||||
<dependency.tika.version>1.27</dependency.tika.version>
|
||||
<dependency.tika.version>2.1.0</dependency.tika.version>
|
||||
<dependency.spring-security.version>5.5.2</dependency.spring-security.version>
|
||||
<dependency.truezip.version>7.7.10</dependency.truezip.version>
|
||||
<dependency.poi.version>4.1.2</dependency.poi.version>
|
||||
@@ -87,10 +86,11 @@
|
||||
<dependency.activemq.version>5.16.1</dependency.activemq.version>
|
||||
<dependency.apache-compress.version>1.21</dependency.apache-compress.version>
|
||||
<dependency.apache.taglibs.version>1.2.5</dependency.apache.taglibs.version>
|
||||
<dependency.awaitility.version>4.1.0</dependency.awaitility.version>
|
||||
<dependency.awaitility.version>4.1.1</dependency.awaitility.version>
|
||||
<dependency.swagger-ui.version>3.38.0</dependency.swagger-ui.version>
|
||||
<dependency.swagger-parser.version>1.0.52</dependency.swagger-parser.version>
|
||||
<dependency.swagger-parser.version>1.0.56</dependency.swagger-parser.version>
|
||||
<dependency.maven-filtering.version>3.1.1</dependency.maven-filtering.version>
|
||||
<dependency.maven-artifact.version>3.8.4</dependency.maven-artifact.version>
|
||||
|
||||
<dependency.jakarta-jaxb-api.version>2.3.3</dependency.jakarta-jaxb-api.version>
|
||||
<dependency.jakarta-ws-api.version>2.3.3</dependency.jakarta-ws-api.version>
|
||||
@@ -109,13 +109,13 @@
|
||||
<alfresco.api-explorer.version>7.1.0.1</alfresco.api-explorer.version> <!-- Also in alfresco-enterprise-share -->
|
||||
<alfresco.maven-plugin.version>2.2.0</alfresco.maven-plugin.version>
|
||||
|
||||
<dependency.postgresql.version>42.2.24</dependency.postgresql.version>
|
||||
<dependency.postgresql.version>42.3.1</dependency.postgresql.version>
|
||||
<dependency.mysql.version>8.0.25</dependency.mysql.version>
|
||||
<dependency.mysql-image.version>8</dependency.mysql-image.version>
|
||||
<dependency.mariadb.version>2.7.4</dependency.mariadb.version>
|
||||
<dependency.tas-utility.version>3.0.45</dependency.tas-utility.version>
|
||||
<dependency.tas-utility.version>3.0.47</dependency.tas-utility.version>
|
||||
<dependency.rest-assured.version>3.3.0</dependency.rest-assured.version>
|
||||
<dependency.tas-restapi.version>1.64</dependency.tas-restapi.version>
|
||||
<dependency.tas-restapi.version>1.65</dependency.tas-restapi.version>
|
||||
<dependency.tas-cmis.version>1.31</dependency.tas-cmis.version>
|
||||
<dependency.tas-email.version>1.8</dependency.tas-email.version>
|
||||
<dependency.tas-webdav.version>1.6</dependency.tas-webdav.version>
|
||||
@@ -143,7 +143,7 @@
|
||||
<connection>scm:git:https://github.com/Alfresco/alfresco-community-repo.git</connection>
|
||||
<developerConnection>scm:git:https://github.com/Alfresco/alfresco-community-repo.git</developerConnection>
|
||||
<url>https://github.com/Alfresco/alfresco-community-repo</url>
|
||||
<tag>HEAD</tag>
|
||||
<tag>14.52</tag>
|
||||
</scm>
|
||||
|
||||
<distributionManagement>
|
||||
@@ -290,11 +290,6 @@
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-mmt</artifactId>
|
||||
<version>${dependency.alfresco-mmt.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-server-root</artifactId>
|
||||
@@ -397,6 +392,11 @@
|
||||
<artifactId>httpclient-cache</artifactId>
|
||||
<version>${dependency.httpclient.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpmime</artifactId>
|
||||
<version>${dependency.httpclient.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.xmlbeans</groupId>
|
||||
<artifactId>xmlbeans</artifactId>
|
||||
@@ -712,7 +712,7 @@
|
||||
<dependency>
|
||||
<groupId>joda-time</groupId>
|
||||
<artifactId>joda-time</artifactId>
|
||||
<version>2.10.12</version>
|
||||
<version>2.10.13</version>
|
||||
</dependency>
|
||||
|
||||
<!-- provided dependencies -->
|
||||
@@ -734,11 +734,6 @@
|
||||
<artifactId>gunit</artifactId>
|
||||
<version>${dependency.antlr.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-all</artifactId>
|
||||
<version>${dependency.mockito-all.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
@@ -871,7 +866,7 @@
|
||||
<plugin>
|
||||
<groupId>io.fabric8</groupId>
|
||||
<artifactId>docker-maven-plugin</artifactId>
|
||||
<version>0.37.0</version>
|
||||
<version>0.38.0</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>14.15-SNAPSHOT</version>
|
||||
<version>14.52</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
@@ -47,7 +47,7 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.santuario</groupId>
|
||||
<artifactId>xmlsec</artifactId>
|
||||
<version>2.2.3</version>
|
||||
<version>2.3.0</version>
|
||||
</dependency>
|
||||
<!-- newer version, see REPO-3133 -->
|
||||
<dependency>
|
||||
@@ -92,6 +92,11 @@
|
||||
<artifactId>spring-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jsoup</groupId>
|
||||
<artifactId>jsoup</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-repository</artifactId>
|
||||
|
@@ -2,7 +2,7 @@
|
||||
* #%L
|
||||
* Alfresco Remote API
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
||||
* Copyright (C) 2005 - 2021 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
@@ -86,7 +86,8 @@ public abstract class CMISServletDispatcher implements CMISDispatcher
|
||||
|
||||
private boolean allowUnsecureCallbackJSONP;
|
||||
|
||||
private Set<String> nonAttachContentTypes = Collections.emptySet(); // pre-configured whitelist, eg. images & pdf
|
||||
// pre-configured allow list of media/mime types, eg. specific types of images & also pdf
|
||||
private Set<String> nonAttachContentTypes = Collections.emptySet();
|
||||
|
||||
public void setTenantAdminService(TenantAdminService tenantAdminService)
|
||||
{
|
||||
@@ -133,9 +134,12 @@ public abstract class CMISServletDispatcher implements CMISDispatcher
|
||||
this.cmisVersion = CmisVersion.fromValue(cmisVersion);
|
||||
}
|
||||
|
||||
public void setNonAttachContentTypes(Set<String> nonAttachWhiteList)
|
||||
public void setNonAttachContentTypes(String nonAttachAllowListStr)
|
||||
{
|
||||
this.nonAttachContentTypes = nonAttachWhiteList;
|
||||
if ((nonAttachAllowListStr != null) && (! nonAttachAllowListStr.isEmpty()))
|
||||
{
|
||||
nonAttachContentTypes = Set.of(nonAttachAllowListStr.trim().split("\\s*,\\s*"));
|
||||
}
|
||||
}
|
||||
|
||||
protected synchronized Descriptor getCurrentDescriptor()
|
||||
|
@@ -44,6 +44,7 @@ import org.alfresco.repo.content.filestore.FileContentReader;
|
||||
import org.alfresco.sync.repo.events.EventPublisher;
|
||||
import org.alfresco.repo.web.util.HttpRangeProcessor;
|
||||
import org.alfresco.rest.framework.resource.content.CacheDirective;
|
||||
import org.alfresco.service.cmr.repository.ArchivedIOException;
|
||||
import org.alfresco.service.cmr.repository.ContentIOException;
|
||||
import org.alfresco.service.cmr.repository.ContentReader;
|
||||
import org.alfresco.service.cmr.repository.ContentService;
|
||||
@@ -449,7 +450,11 @@ public class ContentStreamer implements ResourceLoaderAware
|
||||
if (logger.isInfoEnabled())
|
||||
logger.info("Client aborted stream read:\n\tcontent: " + reader);
|
||||
}
|
||||
catch (ContentIOException e2)
|
||||
catch (ArchivedIOException e2)
|
||||
{
|
||||
throw e2;
|
||||
}
|
||||
catch (ContentIOException e3)
|
||||
{
|
||||
if (logger.isInfoEnabled())
|
||||
logger.info("Client aborted stream read:\n\tcontent: " + reader);
|
||||
|
@@ -1,28 +1,28 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Remote API
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco 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 Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Remote API
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco 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 Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.repo.web.scripts.quickshare;
|
||||
|
||||
import java.util.HashMap;
|
||||
@@ -31,10 +31,12 @@ import java.util.Map;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.alfresco.model.QuickShareModel;
|
||||
import org.alfresco.repo.tenant.TenantUtil;
|
||||
import org.alfresco.service.cmr.quickshare.InvalidSharedIdException;
|
||||
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.util.Pair;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.extensions.webscripts.Cache;
|
||||
@@ -82,14 +84,15 @@ public class UnshareContentDelete extends AbstractQuickShareContent
|
||||
|
||||
try
|
||||
{
|
||||
NodeRef nodeRef = quickShareService.getTenantNodeRefFromSharedId(sharedId).getSecond();
|
||||
Pair<String, NodeRef> pair = quickShareService.getTenantNodeRefFromSharedId(sharedId);
|
||||
String networkTenantDomain = pair.getFirst();
|
||||
|
||||
String sharedBy = (String) nodeService.getProperty(nodeRef, QuickShareModel.PROP_QSHARE_SHAREDBY);
|
||||
if (!quickShareService.canDeleteSharedLink(nodeRef, sharedBy))
|
||||
TenantUtil.runAsSystemTenant(() ->
|
||||
{
|
||||
throw new WebScriptException(HttpServletResponse.SC_FORBIDDEN, "Can't perform unshare action: " + sharedId);
|
||||
}
|
||||
quickShareService.unshareContent(sharedId);
|
||||
checkIfCanDeleteSharedLink(sharedId);
|
||||
quickShareService.unshareContent(sharedId);
|
||||
return null;
|
||||
}, networkTenantDomain);
|
||||
|
||||
Map<String, Object> model = new HashMap<>(1);
|
||||
model.put("success", Boolean.TRUE);
|
||||
@@ -106,4 +109,14 @@ public class UnshareContentDelete extends AbstractQuickShareContent
|
||||
throw new WebScriptException(HttpServletResponse.SC_NOT_FOUND, "Unable to find: " + sharedId);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkIfCanDeleteSharedLink(String sharedId) {
|
||||
NodeRef nodeRef = quickShareService.getTenantNodeRefFromSharedId(sharedId).getSecond();
|
||||
|
||||
String sharedBy = (String) nodeService.getProperty(nodeRef, QuickShareModel.PROP_QSHARE_SHAREDBY);
|
||||
if (!quickShareService.canDeleteSharedLink(nodeRef, sharedBy))
|
||||
{
|
||||
throw new WebScriptException(HttpServletResponse.SC_FORBIDDEN, "Can't perform unshare action: " + sharedId);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Remote API
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2021 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco 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 Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
package org.alfresco.rest.api;
|
||||
|
||||
import org.alfresco.rest.api.model.ContentStorageInfo;
|
||||
import org.alfresco.rest.framework.resource.parameters.Parameters;
|
||||
import org.alfresco.service.Experimental;
|
||||
|
||||
/**
|
||||
* Storage information for content API.
|
||||
* Note: Currently marked as experimental and subject to change.
|
||||
*
|
||||
* @author mpichura
|
||||
*/
|
||||
@Experimental
|
||||
public interface ContentStorageInformation
|
||||
{
|
||||
/**
|
||||
* Note: Currently marked as experimental and subject to change.
|
||||
* @param nodeId Identifier of the node
|
||||
* @param contentPropName Qualified name of content property (e.g. 'cm_content')
|
||||
* @param parameters {@link Parameters} object to get the parameters passed into the request
|
||||
* @return {@link ContentStorageInfo} object consisting of qualified name of content property and a map of storage properties
|
||||
*/
|
||||
@Experimental
|
||||
ContentStorageInfo getStorageInfo(String nodeId, String contentPropName, Parameters parameters);
|
||||
}
|
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Remote API
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2021 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco 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 Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
package org.alfresco.rest.api.impl;
|
||||
|
||||
import org.alfresco.rest.api.ContentStorageInformation;
|
||||
import org.alfresco.rest.api.model.ContentStorageInfo;
|
||||
import org.alfresco.rest.framework.resource.parameters.Parameters;
|
||||
import org.alfresco.service.Experimental;
|
||||
import org.alfresco.service.cmr.repository.ContentService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
import java.util.Map;
|
||||
/**
|
||||
* Default implementation for {@link ContentStorageInformation}
|
||||
* Note: Currently marked as experimental and subject to change.
|
||||
*
|
||||
* @author mpichura
|
||||
*/
|
||||
@Experimental
|
||||
public class ContentStorageInformationImpl implements ContentStorageInformation
|
||||
{
|
||||
|
||||
public static final char PREFIX_SEPARATOR = '_';
|
||||
|
||||
private final ContentService contentService;
|
||||
private final NamespaceService namespaceService;
|
||||
|
||||
public ContentStorageInformationImpl(ContentService contentService, NamespaceService namespaceService)
|
||||
{
|
||||
this.contentService = contentService;
|
||||
this.namespaceService = namespaceService;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
@Experimental
|
||||
public ContentStorageInfo getStorageInfo(String nodeId, String contentPropName, Parameters parameters)
|
||||
{
|
||||
final NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, nodeId);
|
||||
final QName propQName = getQName(contentPropName);
|
||||
final Map<String, String> storageProperties = contentService.getStorageProperties(nodeRef, propQName);
|
||||
final ContentStorageInfo storageInfo = new ContentStorageInfo();
|
||||
storageInfo.setId(propQName.toPrefixString(namespaceService));
|
||||
storageInfo.setStorageProperties(storageProperties);
|
||||
return storageInfo;
|
||||
}
|
||||
|
||||
private QName getQName(final String contentPropName)
|
||||
{
|
||||
final String properContentPropName = contentPropName.replace(PREFIX_SEPARATOR, QName.NAMESPACE_PREFIX);
|
||||
return QName.resolveToQName(namespaceService, properContentPropName);
|
||||
}
|
||||
|
||||
}
|
@@ -25,22 +25,32 @@
|
||||
*/
|
||||
package org.alfresco.rest.api.impl;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.content.ObjectStorageProps;
|
||||
import org.alfresco.repo.download.DownloadModel;
|
||||
import org.alfresco.rest.api.Downloads;
|
||||
import org.alfresco.rest.api.Nodes;
|
||||
import org.alfresco.rest.api.model.Download;
|
||||
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
|
||||
import org.alfresco.rest.framework.core.exceptions.PermissionDeniedException;
|
||||
import org.alfresco.service.Experimental;
|
||||
import org.alfresco.service.cmr.download.DownloadService;
|
||||
import org.alfresco.service.cmr.download.DownloadStatus;
|
||||
import org.alfresco.service.cmr.module.ModuleService;
|
||||
import org.alfresco.service.cmr.repository.ArchivedIOException;
|
||||
import org.alfresco.service.cmr.repository.ContentService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.security.AccessStatus;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -49,23 +59,39 @@ import org.alfresco.service.namespace.QName;
|
||||
*/
|
||||
public class DownloadsImpl implements Downloads
|
||||
{
|
||||
private static Logger logger = LoggerFactory.getLogger(Downloads.class);
|
||||
|
||||
private DownloadService downloadService;
|
||||
private ModuleService moduleService;
|
||||
private NodeService nodeService;
|
||||
private ContentService contentService;
|
||||
private Nodes nodes;
|
||||
private PermissionService permissionService;
|
||||
private int archiveCheckLimit;
|
||||
public static final String DEFAULT_ARCHIVE_NAME = "archive.zip";
|
||||
public static final String DEFAULT_ARCHIVE_EXTENSION = ".zip";
|
||||
public static final String [] CLOUD_CONNECTOR_MODULES = {"org_alfresco_integrations_AzureConnector", "org_alfresco_integrations_S3Connector"};
|
||||
|
||||
public void setDownloadService(DownloadService downloadService)
|
||||
{
|
||||
this.downloadService = downloadService;
|
||||
}
|
||||
|
||||
public void setModuleService(ModuleService moduleService)
|
||||
{
|
||||
this.moduleService = moduleService;
|
||||
}
|
||||
|
||||
public void setNodeService(NodeService nodeService)
|
||||
{
|
||||
this.nodeService = nodeService;
|
||||
}
|
||||
|
||||
public void setContentService(ContentService contentService)
|
||||
{
|
||||
this.contentService = contentService;
|
||||
}
|
||||
|
||||
public void setNodes(Nodes nodes)
|
||||
{
|
||||
this.nodes = nodes;
|
||||
@@ -76,6 +102,11 @@ public class DownloadsImpl implements Downloads
|
||||
this.permissionService = permissionService;
|
||||
}
|
||||
|
||||
public void setArchiveCheckLimit(int checkLimit)
|
||||
{
|
||||
this.archiveCheckLimit = checkLimit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Download createDownloadNode(Download download)
|
||||
{
|
||||
@@ -87,6 +118,8 @@ public class DownloadsImpl implements Downloads
|
||||
|
||||
checkNodeIdsReadPermission(zipContentNodeRefs);
|
||||
|
||||
checkArchiveStatus(zipContentNodeRefs, archiveCheckLimit);
|
||||
|
||||
NodeRef zipNodeRef = downloadService.createDownload(zipContentNodeRefs, true);
|
||||
|
||||
String archiveName = zipContentNodeRefs.length > 1 ?
|
||||
@@ -172,4 +205,95 @@ public class DownloadsImpl implements Downloads
|
||||
return downloadInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the supplied nodes for any content that is archived.
|
||||
* Any folders will be expanded and their children checked.
|
||||
* A limit can be applied to prevent large sized requests preventing the asynchronous call to start.
|
||||
*
|
||||
* @param nodeRefs
|
||||
* @param checkLimit The maximum number of nodes to check, set to -1 for no limit
|
||||
* @see #checkArchiveStatus(NodeRef[], int, Set)
|
||||
*/
|
||||
@Experimental
|
||||
protected void checkArchiveStatus(NodeRef[] nodeRefs, int checkLimit)
|
||||
{
|
||||
if (canCheckArchived())
|
||||
{
|
||||
checkArchiveStatus(nodeRefs, checkLimit, null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the supplied nodes for any content that is archived.
|
||||
* Any folders will be expanded and their children checked.
|
||||
* A limit can be applied to prevent large sized requests preventing the asynchronous call to start.
|
||||
* The cache is used to prevent duplication of checks, as it is possible to provide a folder and its contents as
|
||||
* separate nodes in the download request.
|
||||
*
|
||||
* @param nodeRefs
|
||||
* @param checkLimit The maximum number of nodes to check, set to -1 for no limit
|
||||
* @param cache Tracks nodes that we have already checked, if null an empty cache will be created
|
||||
*/
|
||||
@Experimental
|
||||
private void checkArchiveStatus(NodeRef[] nodeRefs, int checkLimit, Set<NodeRef> cache)
|
||||
{
|
||||
// Create the cache for recursive calls.
|
||||
if (cache == null)
|
||||
{
|
||||
cache = new HashSet<NodeRef>();
|
||||
}
|
||||
|
||||
Set<NodeRef> folders = new HashSet<NodeRef>();
|
||||
for (NodeRef nodeRef : nodeRefs)
|
||||
{
|
||||
// We hit the number of nodes we want to check.
|
||||
if (cache.size() == checkLimit)
|
||||
{
|
||||
if (logger.isInfoEnabled())
|
||||
{
|
||||
logger.info(
|
||||
String.format(
|
||||
"Maximum check of %d reached for archived content. No more checks will be performed and download will still be created.",
|
||||
checkLimit));
|
||||
}
|
||||
return;
|
||||
}
|
||||
// Already checked this node, we can skip.
|
||||
if (cache.contains(nodeRef))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
QName qName = nodeService.getType(nodeRef);
|
||||
if (qName.equals(ContentModel.TYPE_FOLDER))
|
||||
{
|
||||
// We'll check the child nodes at the end in case there are other nodes in this loop that is archived.
|
||||
folders.add(nodeRef);
|
||||
}
|
||||
else if (qName.equals(ContentModel.TYPE_CONTENT))
|
||||
{
|
||||
Map<String, String> props = contentService.getStorageProperties(nodeRef, qName);
|
||||
if (!props.isEmpty() && Boolean.valueOf(props.get(ObjectStorageProps.X_ALF_ARCHIVED.getValue())))
|
||||
{
|
||||
throw new ArchivedIOException("One or more nodes' content is archived and not accessible.");
|
||||
}
|
||||
}
|
||||
cache.add(nodeRef); // No need to check this node again.
|
||||
}
|
||||
|
||||
// We re-run the folder contents at the end in case we hit content that is archived in the first loop and can stop early.
|
||||
for (NodeRef nodeRef : folders)
|
||||
{
|
||||
NodeRef[] childRefs = nodeService.getChildAssocs(nodeRef).stream()
|
||||
.map(childAssoc -> childAssoc.getChildRef())
|
||||
.toArray(NodeRef[]::new);
|
||||
checkArchiveStatus(childRefs, checkLimit, cache); // We'll keep going until we have no more folders in children.
|
||||
}
|
||||
}
|
||||
|
||||
@Experimental
|
||||
protected boolean canCheckArchived()
|
||||
{
|
||||
return Arrays.stream(CLOUD_CONNECTOR_MODULES).anyMatch(m-> moduleService.getModule(m) != null);
|
||||
}
|
||||
}
|
||||
|
@@ -239,11 +239,15 @@ public class NodesImpl implements Nodes
|
||||
|
||||
private ConcurrentHashMap<String,NodeRef> ddCache = new ConcurrentHashMap<>();
|
||||
|
||||
private Set<String> nonAttachContentTypes = Collections.emptySet(); // pre-configured whitelist, eg. images & pdf
|
||||
// pre-configured allow list of media/mime types, eg. specific types of images & also pdf
|
||||
private Set<String> nonAttachContentTypes = Collections.emptySet();
|
||||
|
||||
public void setNonAttachContentTypes(Set<String> nonAttachWhiteList)
|
||||
public void setNonAttachContentTypes(String nonAttachAllowListStr)
|
||||
{
|
||||
this.nonAttachContentTypes = nonAttachWhiteList;
|
||||
if ((nonAttachAllowListStr != null) && (! nonAttachAllowListStr.isEmpty()))
|
||||
{
|
||||
nonAttachContentTypes = Set.of(nonAttachAllowListStr.trim().split("\\s*,\\s*"));
|
||||
}
|
||||
}
|
||||
|
||||
public void init()
|
||||
@@ -3420,7 +3424,7 @@ public class NodesImpl implements Nodes
|
||||
@Override
|
||||
public DirectAccessUrl requestContentDirectUrl(NodeRef nodeRef, boolean attachment, Long validFor)
|
||||
{
|
||||
DirectAccessUrl directAccessUrl = contentService.requestContentDirectUrl(nodeRef, attachment, validFor);
|
||||
DirectAccessUrl directAccessUrl = contentService.requestContentDirectUrl(nodeRef, ContentModel.PROP_CONTENT, attachment, validFor);
|
||||
if (directAccessUrl == null)
|
||||
{
|
||||
throw new DisabledServiceException("Direct access url isn't available.");
|
||||
|
@@ -274,15 +274,15 @@ public class QuickShareLinksImpl implements QuickShareLinks, RecognizedParamsExt
|
||||
|
||||
try
|
||||
{
|
||||
NodeRef nodeRef = quickShareService.getTenantNodeRefFromSharedId(sharedId).getSecond();
|
||||
Pair<String, NodeRef> pair = quickShareService.getTenantNodeRefFromSharedId(sharedId);
|
||||
String networkTenantDomain = pair.getFirst();
|
||||
|
||||
String sharedByUserId = (String)nodeService.getProperty(nodeRef, QuickShareModel.PROP_QSHARE_SHAREDBY);
|
||||
if (!quickShareService.canDeleteSharedLink(nodeRef, sharedByUserId))
|
||||
TenantUtil.runAsSystemTenant(() ->
|
||||
{
|
||||
throw new PermissionDeniedException("Can't perform unshare action: " + sharedId);
|
||||
}
|
||||
|
||||
quickShareService.unshareContent(sharedId);
|
||||
checkIfCanDeleteSharedLink(sharedId);
|
||||
quickShareService.unshareContent(sharedId);
|
||||
return null;
|
||||
}, networkTenantDomain);
|
||||
}
|
||||
catch (InvalidSharedIdException ex)
|
||||
{
|
||||
@@ -698,4 +698,14 @@ public class QuickShareLinksImpl implements QuickShareLinks, RecognizedParamsExt
|
||||
throw new InvalidArgumentException("A valid recipientEmail must be specified.");
|
||||
}
|
||||
}
|
||||
|
||||
private void checkIfCanDeleteSharedLink(String sharedId) {
|
||||
NodeRef nodeRef = quickShareService.getTenantNodeRefFromSharedId(sharedId).getSecond();
|
||||
|
||||
String sharedByUserId = (String)nodeService.getProperty(nodeRef, QuickShareModel.PROP_QSHARE_SHAREDBY);
|
||||
if (!quickShareService.canDeleteSharedLink(nodeRef, sharedByUserId))
|
||||
{
|
||||
throw new PermissionDeniedException("Can't perform unshare action: " + sharedId);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Remote API
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2021 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco 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 Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
package org.alfresco.rest.api.model;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Representation of storage information for content.
|
||||
*
|
||||
* @author mpichura
|
||||
*/
|
||||
public class ContentStorageInfo
|
||||
{
|
||||
|
||||
/**
|
||||
* Qualified name of content property
|
||||
*/
|
||||
private String id;
|
||||
/**
|
||||
* Key-value (String-String) collection representing storage properties of given content
|
||||
*/
|
||||
private Map<String, String> storageProperties;
|
||||
|
||||
public String getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id)
|
||||
{
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Map<String, String> getStorageProperties()
|
||||
{
|
||||
if (storageProperties == null) {
|
||||
storageProperties = new HashMap<>();
|
||||
}
|
||||
return storageProperties;
|
||||
}
|
||||
|
||||
public void setStorageProperties(Map<String, String> storageProperties)
|
||||
{
|
||||
this.storageProperties = storageProperties;
|
||||
}
|
||||
}
|
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Remote API
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2021 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco 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 Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
package org.alfresco.rest.api.nodes;
|
||||
|
||||
import org.alfresco.rest.api.ContentStorageInformation;
|
||||
import org.alfresco.rest.api.model.ContentStorageInfo;
|
||||
import org.alfresco.rest.framework.WebApiDescription;
|
||||
import org.alfresco.rest.framework.core.exceptions.RelationshipResourceNotFoundException;
|
||||
import org.alfresco.rest.framework.resource.RelationshipResource;
|
||||
import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResourceAction;
|
||||
import org.alfresco.rest.framework.resource.parameters.Parameters;
|
||||
import org.alfresco.service.Experimental;
|
||||
import org.alfresco.util.PropertyCheck;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* Node storage information.
|
||||
* Note: Currently marked as experimental and subject to change.
|
||||
*
|
||||
* @author mpichura
|
||||
*/
|
||||
@Experimental
|
||||
@RelationshipResource(name = "storage-info", entityResource = NodesEntityResource.class, title = "Node's content storage information")
|
||||
public class NodeStorageInfoRelation implements RelationshipResourceAction.ReadById<ContentStorageInfo>, InitializingBean
|
||||
{
|
||||
|
||||
private final ContentStorageInformation storageInformation;
|
||||
|
||||
public NodeStorageInfoRelation(ContentStorageInformation storageInformation)
|
||||
{
|
||||
this.storageInformation = storageInformation;
|
||||
}
|
||||
|
||||
@WebApiDescription(title = "Get storage properties",
|
||||
description = "Retrieves storage properties for given node's content",
|
||||
successStatus = HttpServletResponse.SC_OK)
|
||||
@Override
|
||||
public ContentStorageInfo readById(String entityResourceId, String id, Parameters parameters)
|
||||
throws RelationshipResourceNotFoundException
|
||||
{
|
||||
return storageInformation.getStorageInfo(entityResourceId, id, parameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception
|
||||
{
|
||||
PropertyCheck.mandatory(this, "storageInformation", storageInformation);
|
||||
}
|
||||
}
|
@@ -64,6 +64,18 @@ public class ApiException extends PlatformRuntimeException
|
||||
super(msgId, cause);
|
||||
this.msgId = msgId;
|
||||
}
|
||||
|
||||
public ApiException(String msgId, String message)
|
||||
{
|
||||
super(message);
|
||||
this.msgId = msgId;
|
||||
}
|
||||
|
||||
public ApiException(String msgId, String message, Throwable cause)
|
||||
{
|
||||
super(message, cause);
|
||||
this.msgId = msgId;
|
||||
}
|
||||
|
||||
public ApiException(String msgId, Throwable cause, Map<String,Object> additionalState)
|
||||
{
|
||||
|
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Remote API
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2021 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco 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 Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.rest.framework.core.exceptions;
|
||||
|
||||
import org.alfresco.service.Experimental;
|
||||
|
||||
/**
|
||||
* Thrown when the content is archived and not readily accessible.
|
||||
* Status is <i>Precondition Failed</i> client error = 412.
|
||||
*
|
||||
* @author David Edwards
|
||||
*/
|
||||
@Experimental
|
||||
public class ArchivedContentException extends ApiException
|
||||
{
|
||||
|
||||
public static String DEFAULT_MESSAGE_ID = "framework.exception.ArchivedContent";
|
||||
|
||||
public ArchivedContentException()
|
||||
{
|
||||
super(DEFAULT_MESSAGE_ID);
|
||||
}
|
||||
|
||||
public ArchivedContentException(String message)
|
||||
{
|
||||
this(DEFAULT_MESSAGE_ID, message);
|
||||
}
|
||||
|
||||
private ArchivedContentException(String msgId, String message)
|
||||
{
|
||||
super(msgId, message);
|
||||
}
|
||||
|
||||
public ArchivedContentException(Throwable cause)
|
||||
{
|
||||
this(DEFAULT_MESSAGE_ID, cause.getLocalizedMessage(), cause);
|
||||
}
|
||||
|
||||
public ArchivedContentException(String message, Throwable cause)
|
||||
{
|
||||
this(DEFAULT_MESSAGE_ID, message, cause);
|
||||
}
|
||||
|
||||
private ArchivedContentException(String msgId, String message, Throwable cause)
|
||||
{
|
||||
super(msgId, message, cause);
|
||||
}
|
||||
|
||||
}
|
@@ -42,6 +42,7 @@ import org.alfresco.rest.framework.core.ResourceLocator;
|
||||
import org.alfresco.rest.framework.core.ResourceOperation;
|
||||
import org.alfresco.rest.framework.core.ResourceWithMetadata;
|
||||
import org.alfresco.rest.framework.core.exceptions.ApiException;
|
||||
import org.alfresco.rest.framework.core.exceptions.ArchivedContentException;
|
||||
import org.alfresco.rest.framework.resource.actions.ActionExecutor;
|
||||
import org.alfresco.rest.framework.resource.actions.interfaces.BinaryResourceAction;
|
||||
import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResourceBinaryAction;
|
||||
@@ -52,6 +53,8 @@ import org.alfresco.rest.framework.resource.content.FileBinaryResource;
|
||||
import org.alfresco.rest.framework.resource.content.NodeBinaryResource;
|
||||
import org.alfresco.rest.framework.resource.parameters.Params;
|
||||
import org.alfresco.rest.framework.tools.ResponseWriter;
|
||||
import org.alfresco.service.cmr.repository.ArchivedIOException;
|
||||
import org.alfresco.service.cmr.repository.ContentIOException;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
@@ -84,6 +87,8 @@ public abstract class AbstractResourceWebScript extends ApiWebScript implements
|
||||
private ContentStreamer streamer;
|
||||
protected ResourceWebScriptHelper helper;
|
||||
|
||||
private static final String HEADER_CONTENT_LENGTH = "Content-Length";
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Override
|
||||
public void execute(final Api api, final WebScriptRequest req, final WebScriptResponse res) throws IOException
|
||||
@@ -173,6 +178,10 @@ public abstract class AbstractResourceWebScript extends ApiWebScript implements
|
||||
}
|
||||
|
||||
}
|
||||
catch (ContentIOException cioe)
|
||||
{
|
||||
handleContentIOException(res, cioe);
|
||||
}
|
||||
catch (AlfrescoRuntimeException | ApiException | WebScriptException xception )
|
||||
{
|
||||
renderException(xception, res, assistant);
|
||||
@@ -215,6 +224,20 @@ public abstract class AbstractResourceWebScript extends ApiWebScript implements
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
private void handleContentIOException(final WebScriptResponse res, ContentIOException exception) throws IOException
|
||||
{
|
||||
// If the Content-Length is not set back to -1 any client will expect to receive binary and will hang until it times out
|
||||
res.setHeader(HEADER_CONTENT_LENGTH, String.valueOf(-1));
|
||||
if (exception instanceof ArchivedIOException)
|
||||
{
|
||||
renderException(new ArchivedContentException(exception.getMsgId(), exception), res, assistant);
|
||||
}
|
||||
else
|
||||
{
|
||||
renderException(exception, res, assistant);
|
||||
}
|
||||
}
|
||||
|
||||
protected RetryingTransactionHelper getTransactionHelper(String api)
|
||||
{
|
||||
RetryingTransactionHelper transHelper = transactionService.getRetryingTransactionHelper();
|
||||
|
@@ -174,6 +174,7 @@
|
||||
<entry key="org.springframework.http.InvalidMediaTypeException" value="#{T(org.springframework.extensions.webscripts.Status).STATUS_UNSUPPORTED_MEDIA_TYPE}" />
|
||||
<entry key="org.alfresco.rest.framework.core.exceptions.ServiceUnavailableException" value="503" />
|
||||
<entry key="org.alfresco.service.cmr.dictionary.InvalidTypeException" value="409" />
|
||||
<entry key="org.alfresco.rest.framework.core.exceptions.ArchivedContentException" value="#{T(org.springframework.extensions.webscripts.Status).STATUS_PRECONDITION_FAILED}" />
|
||||
</map>
|
||||
</property>
|
||||
</bean>
|
||||
@@ -508,19 +509,6 @@
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="nodes.nonAttachContentTypes" class="org.springframework.beans.factory.config.SetFactoryBean">
|
||||
<property name="sourceSet">
|
||||
<set>
|
||||
<value>application/pdf</value>
|
||||
<value>image/jpeg</value>
|
||||
<value>image/gif</value>
|
||||
<value>image/png</value>
|
||||
<value>image/tiff</value>
|
||||
<value>image/bmp</value>
|
||||
</set>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="nodes.personLookupProperties" class="org.springframework.beans.factory.config.SetFactoryBean">
|
||||
<property name="sourceSet">
|
||||
<set>
|
||||
@@ -541,7 +529,7 @@
|
||||
<property name="quickShareLinks" ref="QuickShareLinks"/>
|
||||
<property name="behaviourFilter" ref="policyBehaviourFilter"/>
|
||||
<property name="ignoreTypes" ref="nodes.ignoreTypes"/>
|
||||
<property name="nonAttachContentTypes" ref="nodes.nonAttachContentTypes"/>
|
||||
<property name="nonAttachContentTypes" value="${content.nonAttach.mimetypes}"/>
|
||||
<property name="personLookupProperties" ref="nodes.personLookupProperties"/>
|
||||
<property name="poster" ref="activitiesPoster" />
|
||||
<property name="smartStore" ref="smartStore"/>
|
||||
@@ -564,8 +552,11 @@
|
||||
<bean id="downloads" class="org.alfresco.rest.api.impl.DownloadsImpl">
|
||||
<property name="downloadService" ref="DownloadService"/>
|
||||
<property name="nodeService" ref="NodeService"/>
|
||||
<property name="contentService" ref="ContentService"/>
|
||||
<property name="moduleService" ref="ModuleService"/>
|
||||
<property name="nodes" ref="Nodes" />
|
||||
<property name="permissionService" ref="permissionService"/>
|
||||
<property name="archiveCheckLimit" value="${download.archiveCheckLimit}"/>
|
||||
</bean>
|
||||
|
||||
<bean id="actions" class="org.alfresco.rest.api.impl.ActionsImpl">
|
||||
@@ -605,6 +596,26 @@
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="contentStorageInformation" class="org.alfresco.rest.api.impl.ContentStorageInformationImpl">
|
||||
<constructor-arg name="contentService" ref="ContentService"/>
|
||||
<constructor-arg name="namespaceService" ref="NamespaceService"/>
|
||||
</bean>
|
||||
|
||||
<bean id="ContentStorageInformation" class="org.springframework.aop.framework.ProxyFactoryBean">
|
||||
<property name="proxyInterfaces">
|
||||
<value>org.alfresco.rest.api.ContentStorageInformation</value>
|
||||
</property>
|
||||
<property name="target">
|
||||
<ref bean="contentStorageInformation" />
|
||||
</property>
|
||||
<property name="interceptorNames">
|
||||
<list>
|
||||
<idref bean="legacyExceptionInterceptor" />
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="deletedNodes" class="org.alfresco.rest.api.impl.DeletedNodesImpl">
|
||||
<property name="nodes" ref="Nodes" />
|
||||
<property name="nodeService" ref="NodeService" />
|
||||
@@ -976,7 +987,11 @@
|
||||
<property name="behaviourFilter" ref="policyBehaviourFilter"/>
|
||||
<property name="directAccessUrlHelper" ref="directAccessUrlHelper" />
|
||||
</bean>
|
||||
|
||||
|
||||
<bean class="org.alfresco.rest.api.nodes.NodeStorageInfoRelation">
|
||||
<constructor-arg name="storageInformation" ref="ContentStorageInformation" />
|
||||
</bean>
|
||||
|
||||
<bean class="org.alfresco.rest.api.nodes.NodeSecondaryChildrenRelation" parent="baseNodeRelation"/>
|
||||
|
||||
<bean class="org.alfresco.rest.api.nodes.NodeParentsRelation" parent="baseNodeRelation"/>
|
||||
@@ -1114,7 +1129,7 @@
|
||||
<property name="version" value="1.0"/>
|
||||
<property name="cmisVersion" value="1.0"/>
|
||||
<property name="tenantAdminService" ref="tenantAdminService"/>
|
||||
<property name="nonAttachContentTypes" ref="nodes.nonAttachContentTypes"/>
|
||||
<property name="nonAttachContentTypes" value="${content.nonAttach.mimetypes}"/>
|
||||
</bean>
|
||||
|
||||
<bean id="cmisAtomPubDispatcher1.1" class="org.alfresco.opencmis.PublicApiAtomPubCMISDispatcher" init-method="init">
|
||||
@@ -1126,7 +1141,7 @@
|
||||
<property name="version" value="1.1"/>
|
||||
<property name="cmisVersion" value="1.1"/>
|
||||
<property name="tenantAdminService" ref="tenantAdminService"/>
|
||||
<property name="nonAttachContentTypes" ref="nodes.nonAttachContentTypes"/>
|
||||
<property name="nonAttachContentTypes" value="${content.nonAttach.mimetypes}"/>
|
||||
</bean>
|
||||
|
||||
<bean id="cmisBrowserDispatcher1.1" class="org.alfresco.opencmis.PublicApiBrowserCMISDispatcher" init-method="init">
|
||||
@@ -1138,7 +1153,7 @@
|
||||
<property name="version" value="1.1"/>
|
||||
<property name="cmisVersion" value="1.1"/>
|
||||
<property name="tenantAdminService" ref="tenantAdminService"/>
|
||||
<property name="nonAttachContentTypes" ref="nodes.nonAttachContentTypes"/>
|
||||
<property name="nonAttachContentTypes" value="${content.nonAttach.mimetypes}"/>
|
||||
<property name="allowUnsecureCallbackJSONP" value="${allow.unsecure.callback.jsonp}"/>
|
||||
</bean>
|
||||
|
||||
|
@@ -33,7 +33,7 @@
|
||||
<#elseif v?is_number>
|
||||
${v?c}
|
||||
<#elseif v?is_string>
|
||||
"${v?string}"
|
||||
"${v?html}"
|
||||
<#elseif v?is_hash>
|
||||
<#if v?keys?size gt maxDepth >
|
||||
<#stop "Max depth of object achieved">
|
||||
@@ -188,7 +188,7 @@ ${url.serviceContext}/api/node/${nodeRef?replace("://","/")}/content;${prop?url}
|
||||
</tr>
|
||||
<#list result.children as n>
|
||||
<tr>
|
||||
<td><a href="#" onclick="AdminConsole_childClick('${n.childRef}');return false;">${n.QName}</a></td>
|
||||
<td><a href="#" onclick="AdminConsole_childClick('${n.childRef}');return false;">${n.QName?html}</a></td>
|
||||
<td><a href="#" onclick="AdminConsole_childClick('${n.childRef}');return false;">${n.childRef}</a></td>
|
||||
<td>${n.primary?string}</td>
|
||||
<td>${n.typeQName}</td>
|
||||
@@ -222,7 +222,7 @@ ${url.serviceContext}/api/node/${nodeRef?replace("://","/")}/content;${prop?url}
|
||||
</tr>
|
||||
<#list result.parents as p>
|
||||
<tr>
|
||||
<td>${p.name.prefixedName}</td>
|
||||
<td>${p.name.prefixedName?html}</td>
|
||||
<td>${p.parentTypeName.prefixedName}</td>
|
||||
<td><a href="#" onclick="AdminConsole_parentClick('${p.parentRef}');return false;">${p.parentRef}</a></td></td>
|
||||
<td>${p.primary?string}</td>
|
||||
@@ -280,7 +280,7 @@ ${url.serviceContext}/api/node/${nodeRef?replace("://","/")}/content;${prop?url}
|
||||
<@section label=msg("nodebrowser.permissions") />
|
||||
<table id="perminfo-table" class="node">
|
||||
<tr><td>${msg("nodebrowser.inherits")}: ${result.permissions.inherit?string}</td></tr>
|
||||
<tr><td>${msg("nodebrowser.owner")}: ${result.permissions.owner!""}</td></tr>
|
||||
<tr><td>${msg("nodebrowser.owner")}: <#if result.permissions.owner??>${result.permissions.owner?html}</#if></td></tr>
|
||||
</table>
|
||||
<table id="permissions-table" class="node grid">
|
||||
<tr>
|
||||
@@ -291,7 +291,7 @@ ${url.serviceContext}/api/node/${nodeRef?replace("://","/")}/content;${prop?url}
|
||||
<#list result.permissions.entries as p>
|
||||
<tr>
|
||||
<td>${p.permission}</td>
|
||||
<td>${p.authority}</td>
|
||||
<td>${p.authority?html}</td>
|
||||
<td>${p.accessStatus}</td>
|
||||
</tr>
|
||||
</#list>
|
||||
|
@@ -76,6 +76,7 @@ import org.junit.runners.Suite;
|
||||
org.alfresco.repo.web.scripts.site.SurfConfigTest.class,
|
||||
org.alfresco.repo.web.scripts.node.NodeWebScripTest.class,
|
||||
org.alfresco.rest.api.impl.CommentsImplUnitTest.class,
|
||||
org.alfresco.rest.api.impl.DownloadsImplCheckArchiveStatusUnitTest.class,
|
||||
org.alfresco.rest.api.impl.RestApiDirectUrlConfigUnitTest.class
|
||||
})
|
||||
public class AppContext04TestSuite
|
||||
|
@@ -37,7 +37,6 @@ import org.alfresco.service.cmr.security.MutableAuthenticationService;
|
||||
import org.alfresco.service.cmr.security.PersonService;
|
||||
import org.alfresco.util.BaseSpringTest;
|
||||
import org.alfresco.util.PropertyMap;
|
||||
import org.alfresco.util.testing.category.FrequentlyFailingTests;
|
||||
import org.alfresco.util.testing.category.IntermittentlyFailingTests;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
|
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Remote API
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2021 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco 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 Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
package org.alfresco.rest.api.impl;
|
||||
|
||||
import org.alfresco.rest.api.model.ContentStorageInfo;
|
||||
import org.alfresco.service.cmr.repository.ContentService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class ContentStorageInformationImplTest
|
||||
{
|
||||
@Mock
|
||||
private ContentService contentService;
|
||||
@Mock
|
||||
private NamespaceService namespaceService;
|
||||
|
||||
@InjectMocks
|
||||
private ContentStorageInformationImpl objectUnderTest;
|
||||
|
||||
@Test
|
||||
public void shouldReturnStorageInfoResponseWithNonEmptyStorageProps()
|
||||
{
|
||||
|
||||
final String nodeId = "dummy-node-id";
|
||||
final NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, nodeId);
|
||||
final String contentPropName = "cm:content";
|
||||
|
||||
final Map<String, String> storageProps = Map.of("x-amz-storage-class", "INTELLIGENT_TIERING", "x-alf-archived", "false");
|
||||
Mockito.when(contentService.getStorageProperties(Mockito.eq(nodeRef), Mockito.any())).thenReturn(storageProps);
|
||||
Mockito.when(namespaceService.getNamespaceURI(NamespaceService.CONTENT_MODEL_PREFIX))
|
||||
.thenReturn(NamespaceService.CONTENT_MODEL_1_0_URI);
|
||||
Mockito.when(namespaceService.getPrefixes(NamespaceService.CONTENT_MODEL_1_0_URI))
|
||||
.thenReturn(List.of(NamespaceService.CONTENT_MODEL_PREFIX));
|
||||
|
||||
final ContentStorageInfo storageInfo = objectUnderTest.getStorageInfo(nodeId, contentPropName, null);
|
||||
|
||||
Assert.assertEquals(storageProps, storageInfo.getStorageProperties());
|
||||
Assert.assertEquals(storageInfo.getId(), contentPropName);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnStorageInfoResponseWithEmptyStorageProps()
|
||||
{
|
||||
final String nodeId = "dummy-node-id";
|
||||
final NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, nodeId);
|
||||
final String contentPropName = "cm:content";
|
||||
|
||||
Mockito.when(contentService.getStorageProperties(Mockito.eq(nodeRef), Mockito.any())).thenCallRealMethod();
|
||||
Mockito.when(namespaceService.getNamespaceURI(NamespaceService.CONTENT_MODEL_PREFIX))
|
||||
.thenReturn(NamespaceService.CONTENT_MODEL_1_0_URI);
|
||||
Mockito.when(namespaceService.getPrefixes(NamespaceService.CONTENT_MODEL_1_0_URI))
|
||||
.thenReturn(List.of(NamespaceService.CONTENT_MODEL_PREFIX));
|
||||
|
||||
final ContentStorageInfo storageInfo = objectUnderTest.getStorageInfo(nodeId, contentPropName, null);
|
||||
|
||||
Assert.assertEquals(Collections.emptyMap(), storageInfo.getStorageProperties());
|
||||
Assert.assertEquals(storageInfo.getId(), contentPropName);
|
||||
}
|
||||
}
|
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Remote API
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2021 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco 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 Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.rest.api.impl;
|
||||
|
||||
import static org.alfresco.model.ContentModel.TYPE_CONTENT;
|
||||
import static org.alfresco.model.ContentModel.TYPE_FOLDER;
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.repo.content.ObjectStorageProps;
|
||||
import org.alfresco.repo.module.ModuleDetailsImpl;
|
||||
import org.alfresco.rest.api.Nodes;
|
||||
import org.alfresco.service.cmr.download.DownloadService;
|
||||
import org.alfresco.service.cmr.module.ModuleDetails;
|
||||
import org.alfresco.service.cmr.module.ModuleService;
|
||||
import org.alfresco.service.cmr.repository.ArchivedIOException;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
import org.alfresco.service.cmr.repository.ContentService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class DownloadsImplCheckArchiveStatusUnitTest
|
||||
{
|
||||
@InjectMocks
|
||||
private final DownloadsImpl downloads = new DownloadsImpl();
|
||||
|
||||
@Mock
|
||||
private DownloadService downloadService;
|
||||
@Mock
|
||||
private ModuleService moduleService;
|
||||
@Mock
|
||||
private NodeService nodeService;
|
||||
@Mock
|
||||
private ContentService contentService;
|
||||
@Mock
|
||||
private Nodes nodes;
|
||||
@Mock
|
||||
private PermissionService permissionService;
|
||||
|
||||
private final NodeRef contentNode1 = new NodeRef("://Content:/Node1");
|
||||
private final NodeRef contentNode2 = new NodeRef("://Content:/Node2");
|
||||
private final NodeRef contentNode3 = new NodeRef("://Content:/Node3");
|
||||
private final NodeRef contentNode4 = new NodeRef("://Content:/Node4");
|
||||
private final NodeRef contentNode5 = new NodeRef("://Content:/Node5");
|
||||
private final NodeRef contentNode6 = new NodeRef("://Content:/Node6");
|
||||
private final NodeRef folderParent1 = new NodeRef("://Folder:/Parent1");
|
||||
private final NodeRef folderParent2 = new NodeRef("://Folder:/Parent2");
|
||||
private final NodeRef folder1 = new NodeRef("://Folder:/1");
|
||||
private final NodeRef folder2 = new NodeRef("://Folder:/2");
|
||||
|
||||
// folderParent1
|
||||
private final List<ChildAssociationRef> folderParent1ChildAssocs = List.of(
|
||||
new ChildAssociationRef(TYPE_FOLDER, folderParent1, TYPE_CONTENT, contentNode3),
|
||||
new ChildAssociationRef(TYPE_FOLDER, folderParent1, TYPE_CONTENT, contentNode4),
|
||||
new ChildAssociationRef(TYPE_FOLDER, folderParent1, TYPE_CONTENT, contentNode5),
|
||||
new ChildAssociationRef(TYPE_FOLDER, folderParent1, TYPE_FOLDER, folder2),
|
||||
new ChildAssociationRef(TYPE_FOLDER, folderParent1, TYPE_FOLDER, folderParent2)
|
||||
);
|
||||
|
||||
// folderParent2
|
||||
private final List<ChildAssociationRef> folderParent2ChildAssocs = List.of(
|
||||
new ChildAssociationRef(TYPE_FOLDER, folderParent2, TYPE_FOLDER, folder1)
|
||||
);
|
||||
|
||||
// folder1
|
||||
private final List<ChildAssociationRef> folder1ChildAssocs = List.of(
|
||||
new ChildAssociationRef(TYPE_FOLDER, folder1, TYPE_CONTENT, contentNode1),
|
||||
new ChildAssociationRef(TYPE_FOLDER, folder1, TYPE_CONTENT, contentNode5),
|
||||
new ChildAssociationRef(TYPE_FOLDER, folder1, TYPE_CONTENT, contentNode6)
|
||||
);
|
||||
|
||||
// folder2 empty
|
||||
private final List<ChildAssociationRef> folder2ChildAssocs = List.of();
|
||||
|
||||
|
||||
private final Map<String, String> archivedProps = Map.of(ObjectStorageProps.X_ALF_ARCHIVED.getValue(), "true");
|
||||
private final Map<String, String> nonArchivedProps = Map.of(ObjectStorageProps.X_ALF_ARCHIVED.getValue(), "false");
|
||||
|
||||
private final ModuleDetails mockDetails = new ModuleDetailsImpl("id", null, "title", "description"); // doesn't need to do anything, just exist
|
||||
|
||||
private final NodeRef[] nodeRefsToTest = { contentNode1, contentNode2, folderParent1, folder1 };
|
||||
|
||||
@Before
|
||||
public void setup()
|
||||
{
|
||||
when(nodeService.getType(any())).thenReturn(TYPE_CONTENT);
|
||||
when(nodeService.getType(folderParent1)).thenReturn(TYPE_FOLDER);
|
||||
when(nodeService.getType(folderParent2)).thenReturn(TYPE_FOLDER);
|
||||
when(nodeService.getType(folder1)).thenReturn(TYPE_FOLDER);
|
||||
when(nodeService.getType(folder2)).thenReturn(TYPE_FOLDER);
|
||||
|
||||
when(nodeService.getChildAssocs(folderParent1)).thenReturn(folderParent1ChildAssocs);
|
||||
when(nodeService.getChildAssocs(folderParent2)).thenReturn(folderParent2ChildAssocs);
|
||||
when(nodeService.getChildAssocs(folder1)).thenReturn(folder1ChildAssocs);
|
||||
when(nodeService.getChildAssocs(folder2)).thenReturn(folder2ChildAssocs);
|
||||
|
||||
when(moduleService.getModule("org_alfresco_integrations_S3Connector")).thenReturn(mockDetails);
|
||||
|
||||
final NodeRef[] childNodeRefsExpectedFolderParent1 = { contentNode3, contentNode4, contentNode5, folder2, folderParent2 };
|
||||
final NodeRef[] childNodeRefsExpectedFolderParent2 = { folder1 };
|
||||
final NodeRef[] childNodeRefsExpectedFolder1 = { contentNode1, contentNode5, contentNode6 };
|
||||
final NodeRef[] childNodeRefsExpectedFolder2 = {};
|
||||
|
||||
assertChildNodeRefMocks(folderParent1, childNodeRefsExpectedFolderParent1);
|
||||
assertChildNodeRefMocks(folderParent2, childNodeRefsExpectedFolderParent2);
|
||||
assertChildNodeRefMocks(folder1, childNodeRefsExpectedFolder1);
|
||||
assertChildNodeRefMocks(folder2, childNodeRefsExpectedFolder2);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testAllPass()
|
||||
{
|
||||
when(contentService.getStorageProperties(any(NodeRef.class), any(QName.class))).thenReturn(nonArchivedProps);
|
||||
|
||||
// No archived nodes, each content node should only be checked once
|
||||
downloads.checkArchiveStatus(nodeRefsToTest, -1);
|
||||
|
||||
verify(contentService, times(1)).getStorageProperties(contentNode1, TYPE_CONTENT);
|
||||
verify(contentService, times(1)).getStorageProperties(contentNode2, TYPE_CONTENT);
|
||||
verify(contentService, times(1)).getStorageProperties(contentNode3, TYPE_CONTENT);
|
||||
verify(contentService, times(1)).getStorageProperties(contentNode4, TYPE_CONTENT);
|
||||
verify(contentService, times(1)).getStorageProperties(contentNode5, TYPE_CONTENT);
|
||||
verify(contentService, times(1)).getStorageProperties(contentNode6, TYPE_CONTENT);
|
||||
verifyNoMoreInteractions(contentService);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFirstItemArchived()
|
||||
{
|
||||
when(contentService.getStorageProperties(contentNode1, TYPE_CONTENT)).thenReturn(archivedProps);
|
||||
|
||||
assertThrows(ArchivedIOException.class, () -> downloads.checkArchiveStatus(nodeRefsToTest, -1));
|
||||
|
||||
verify(contentService, times(1)).getStorageProperties(contentNode1, TYPE_CONTENT);
|
||||
verifyNoMoreInteractions(contentService);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testContentNode3Archived()
|
||||
{
|
||||
// fail node3 (within another folder)
|
||||
when(contentService.getStorageProperties(any(NodeRef.class), any(QName.class))).thenReturn(nonArchivedProps);
|
||||
when(contentService.getStorageProperties(contentNode3, TYPE_CONTENT)).thenReturn(archivedProps);
|
||||
|
||||
assertThrows(ArchivedIOException.class, () -> downloads.checkArchiveStatus(nodeRefsToTest, -1));
|
||||
|
||||
verify(contentService, times(1)).getStorageProperties(contentNode1, TYPE_CONTENT);
|
||||
verify(contentService, times(1)).getStorageProperties(contentNode2, TYPE_CONTENT);
|
||||
verify(contentService, times(1)).getStorageProperties(contentNode3, TYPE_CONTENT);
|
||||
verify(contentService, times(1)).getStorageProperties(contentNode5, TYPE_CONTENT);
|
||||
verify(contentService, times(1)).getStorageProperties(contentNode6, TYPE_CONTENT);
|
||||
verifyNoMoreInteractions(contentService);
|
||||
}
|
||||
|
||||
private void assertChildNodeRefMocks(final NodeRef nodeRef, final NodeRef[] expecteds)
|
||||
{
|
||||
final NodeRef[] actuals = nodeService.getChildAssocs(nodeRef).stream()
|
||||
.map(childAssoc -> childAssoc.getChildRef())
|
||||
.toArray(NodeRef[]::new);
|
||||
assertArrayEquals(expecteds, actuals);
|
||||
}
|
||||
}
|
@@ -2,7 +2,7 @@
|
||||
* #%L
|
||||
* Alfresco Remote API
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2020 Alfresco Software Limited
|
||||
* Copyright (C) 2005 - 2021 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
@@ -25,7 +25,6 @@
|
||||
*/
|
||||
package org.alfresco.rest.api.tests;
|
||||
|
||||
import org.alfresco.repo.action.ActionServiceImpl;
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.repo.quickshare.QuickShareLinkExpiryActionImpl;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
@@ -65,7 +64,6 @@ import org.alfresco.service.cmr.search.SearchService;
|
||||
import org.alfresco.service.cmr.security.AccessStatus;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.service.cmr.site.SiteVisibility;
|
||||
import org.alfresco.util.testing.category.FrequentlyFailingTests;
|
||||
import org.alfresco.util.testing.category.LuceneTests;
|
||||
import org.alfresco.util.testing.category.RedundantTests;
|
||||
import org.joda.time.DateTime;
|
||||
|
@@ -82,8 +82,7 @@ Sometimes it is desirable to create a version automatically. Whether this happe
|
||||
When _cm:autoVersion_ is true, a new version is created when the _cm:content_ of a content node changes.
|
||||
When _cm:autoVersionOnUpdateProps_ is true, a new version is created when any of the properties of a content node change.
|
||||
|
||||
The defaults for these properties are set in the contentModel.xml file in the usual way. But to simplify the admin experience, the values of these properties can also set using global properties:
|
||||
|
||||
The defaults for these properties are set in the contentModel.xml file in the usual way. But to simplify the admin experience, the values of these properties can also be set using global properties:
|
||||
* version.store.enableAutoVersioning
|
||||
* version.store.enableAutoVersionOnUpdateProps
|
||||
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>14.15-SNAPSHOT</version>
|
||||
<version>14.52</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
@@ -67,6 +67,11 @@
|
||||
<artifactId>jakarta.mail</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpmime</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-dbcp</groupId>
|
||||
<artifactId>commons-dbcp</artifactId>
|
||||
@@ -191,7 +196,7 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.maven</groupId>
|
||||
<artifactId>maven-artifact</artifactId>
|
||||
<version>3.8.3</version>
|
||||
<version>${dependency.maven-artifact.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>de.schlichtherle.truezip</groupId>
|
||||
@@ -383,7 +388,7 @@
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.woodstox</groupId>
|
||||
<artifactId>woodstox-core</artifactId>
|
||||
<version>6.2.6</version>
|
||||
<version>6.2.7</version>
|
||||
</dependency>
|
||||
|
||||
<!-- GData -->
|
||||
|
@@ -26,12 +26,6 @@
|
||||
|
||||
package org.alfresco.repo.admin.patch.impl;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.admin.patch.AsynchronousPatch;
|
||||
import org.alfresco.repo.admin.patch.PatchExecuter;
|
||||
@@ -55,6 +49,12 @@ import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.extensions.surf.util.I18NUtil;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Patch to add <i>cm:indexControl</i> aspect to sites' surf-config folders and
|
||||
* their children as well as to the shared surf-config folder(s) and its/their children.
|
||||
@@ -382,8 +382,12 @@ public class SurfConfigFolderPatch extends AsynchronousPatch
|
||||
this.siteTypeQNameId = qnameDAO.getQName(SiteModel.TYPE_SITE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized int getTotalEstimatedWorkSize()
|
||||
@Override public synchronized int getTotalEstimatedWorkSize()
|
||||
{
|
||||
return (int) getTotalEstimatedWorkSizeLong();
|
||||
}
|
||||
|
||||
@Override public synchronized long getTotalEstimatedWorkSizeLong()
|
||||
{
|
||||
if (maxId == Long.MAX_VALUE)
|
||||
{
|
||||
@@ -405,7 +409,7 @@ public class SurfConfigFolderPatch extends AsynchronousPatch
|
||||
logger.debug("\tQ: Work count: " + workCount);
|
||||
}
|
||||
}
|
||||
return (int) workCount;
|
||||
return workCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -25,6 +25,18 @@
|
||||
*/
|
||||
package org.alfresco.repo.batch;
|
||||
|
||||
import org.alfresco.api.AlfrescoPublicApi;
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.repo.node.integrity.IntegrityException;
|
||||
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||
import org.alfresco.util.TraceableThreadFactory;
|
||||
import org.alfresco.util.transaction.TransactionListenerAdapter;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
@@ -43,18 +55,6 @@ import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.alfresco.api.AlfrescoPublicApi;
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.repo.node.integrity.IntegrityException;
|
||||
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||
import org.alfresco.util.TraceableThreadFactory;
|
||||
import org.alfresco.util.transaction.TransactionListenerAdapter;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
|
||||
/**
|
||||
* A <code>BatchProcessor</code> manages the running and monitoring of a potentially long-running transactional batch
|
||||
* process. It iterates over a collection, and queues jobs that fire a worker on a batch of members. The queued jobs
|
||||
@@ -158,10 +158,17 @@ public class BatchProcessor<T> implements BatchMonitor
|
||||
new BatchProcessWorkProvider<T>()
|
||||
{
|
||||
boolean hasMore = true;
|
||||
public int getTotalEstimatedWorkSize()
|
||||
|
||||
@Override public int getTotalEstimatedWorkSize()
|
||||
{
|
||||
return (int) getTotalEstimatedWorkSizeLong();
|
||||
}
|
||||
|
||||
@Override public long getTotalEstimatedWorkSizeLong()
|
||||
{
|
||||
return collection.size();
|
||||
}
|
||||
|
||||
public Collection<T> getNextWork()
|
||||
{
|
||||
// Only return the collection once
|
||||
|
@@ -47,6 +47,7 @@ import org.alfresco.api.AlfrescoPublicApi;
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.repo.content.filestore.FileContentWriter;
|
||||
import org.alfresco.repo.content.transform.TransformerDebug;
|
||||
import org.alfresco.service.cmr.repository.ArchivedIOException;
|
||||
import org.alfresco.service.cmr.repository.ContentAccessor;
|
||||
import org.alfresco.service.cmr.repository.ContentIOException;
|
||||
import org.alfresco.service.cmr.repository.ContentReader;
|
||||
@@ -429,6 +430,7 @@ public abstract class AbstractContentReader extends AbstractContentAccessor impl
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
if (e instanceof ArchivedIOException) throw e;
|
||||
throw new ContentIOException("Failed to open stream onto channel: \n" +
|
||||
" accessor: " + this,
|
||||
e);
|
||||
@@ -541,6 +543,10 @@ public abstract class AbstractContentReader extends AbstractContentAccessor impl
|
||||
// done
|
||||
return content;
|
||||
}
|
||||
catch (ArchivedIOException e)
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new ContentIOException("Failed to copy content to string: \n" +
|
||||
|
@@ -1,44 +1,48 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco 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 Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2021 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco 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 Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.repo.content;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.repo.cache.SimpleCache;
|
||||
import org.alfresco.service.cmr.repository.ContentIOException;
|
||||
import org.alfresco.service.cmr.repository.ContentReader;
|
||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
import org.alfresco.util.GUID;
|
||||
import org.alfresco.util.Pair;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import java.io.Serializable;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.repo.cache.SimpleCache;
|
||||
import org.alfresco.service.Experimental;
|
||||
import org.alfresco.service.cmr.repository.ContentIOException;
|
||||
import org.alfresco.service.cmr.repository.ContentReader;
|
||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
import org.alfresco.util.GUID;
|
||||
import org.alfresco.util.Pair;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* A store providing support for content store implementations that provide
|
||||
@@ -416,4 +420,78 @@ public abstract class AbstractRoutingContentStore implements ContentStore
|
||||
}
|
||||
return deleted;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
@Experimental
|
||||
public Map<String, String> getStorageProperties(String contentUrl)
|
||||
{
|
||||
ContentStore contentStore = selectReadStore(contentUrl);
|
||||
|
||||
if (contentStore == null)
|
||||
{
|
||||
logNoContentStore(contentUrl);
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
final String message = "Getting storage properties from store: ";
|
||||
logExecution(contentUrl, contentStore, message);
|
||||
|
||||
return contentStore.getStorageProperties(contentUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
@Experimental
|
||||
public boolean requestSendContentToArchive(String contentUrl, Map<String, Serializable> archiveParams)
|
||||
{
|
||||
final ContentStore contentStore = selectReadStore(contentUrl);
|
||||
if (contentStore == null)
|
||||
{
|
||||
logNoContentStore(contentUrl);
|
||||
return ContentStore.super.requestSendContentToArchive(contentUrl, archiveParams);
|
||||
}
|
||||
final String message = "Sending content to archive: ";
|
||||
logExecution(contentUrl, contentStore, message);
|
||||
return contentStore.requestSendContentToArchive(contentUrl, archiveParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
@Experimental
|
||||
public boolean requestRestoreContentFromArchive(String contentUrl, Map<String, Serializable> restoreParams)
|
||||
{
|
||||
final ContentStore contentStore = selectReadStore(contentUrl);
|
||||
if (contentStore == null)
|
||||
{
|
||||
logNoContentStore(contentUrl);
|
||||
return ContentStore.super.requestRestoreContentFromArchive(contentUrl, restoreParams);
|
||||
}
|
||||
final String message = "Restoring content from archive: ";
|
||||
logExecution(contentUrl, contentStore, message);
|
||||
return ContentStore.super.requestRestoreContentFromArchive(contentUrl, restoreParams);
|
||||
}
|
||||
|
||||
private void logExecution(final String contentUrl, final ContentStore contentStore, final String message)
|
||||
{
|
||||
if (logger.isTraceEnabled())
|
||||
{
|
||||
logger.trace(message + "\n" +
|
||||
" Content URL: " + contentUrl + "\n" +
|
||||
" Store: " + contentStore);
|
||||
}
|
||||
}
|
||||
|
||||
private void logNoContentStore(String contentUrl)
|
||||
{
|
||||
if (logger.isTraceEnabled())
|
||||
{
|
||||
logger.trace("Content Store not found for content URL: " + contentUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -28,6 +28,7 @@ package org.alfresco.repo.content;
|
||||
import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -45,6 +46,7 @@ import org.alfresco.repo.policy.ClassPolicyDelegate;
|
||||
import org.alfresco.repo.policy.JavaBehaviour;
|
||||
import org.alfresco.repo.policy.PolicyComponent;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
||||
import org.alfresco.service.Experimental;
|
||||
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.dictionary.InvalidTypeException;
|
||||
@@ -103,6 +105,9 @@ public class ContentServiceImpl implements ContentService, ApplicationContextAwa
|
||||
|
||||
private SystemWideDirectUrlConfig systemWideDirectUrlConfig;
|
||||
|
||||
/** pre-configured allow list of media/mime types, eg. specific types of images & also pdf */
|
||||
private Set<String> nonAttachContentTypes = Collections.emptySet();
|
||||
|
||||
/**
|
||||
* The policy component
|
||||
*/
|
||||
@@ -150,6 +155,14 @@ public class ContentServiceImpl implements ContentService, ApplicationContextAwa
|
||||
this.systemWideDirectUrlConfig = systemWideDirectUrlConfig;
|
||||
}
|
||||
|
||||
public void setNonAttachContentTypes(String nonAttachAllowListStr)
|
||||
{
|
||||
if ((nonAttachAllowListStr != null) && (! nonAttachAllowListStr.isEmpty()))
|
||||
{
|
||||
nonAttachContentTypes = Set.of(nonAttachAllowListStr.trim().split("\\s*,\\s*"));
|
||||
}
|
||||
}
|
||||
|
||||
public void setPolicyComponent(PolicyComponent policyComponent)
|
||||
{
|
||||
this.policyComponent = policyComponent;
|
||||
@@ -590,14 +603,14 @@ public class ContentServiceImpl implements ContentService, ApplicationContextAwa
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean isContentDirectUrlEnabled(NodeRef nodeRef)
|
||||
public boolean isContentDirectUrlEnabled(NodeRef nodeRef, QName propertyQName)
|
||||
{
|
||||
boolean contentDirectUrlEnabled = false;
|
||||
|
||||
// TODO: update this
|
||||
if (systemWideDirectUrlConfig.isEnabled())
|
||||
{
|
||||
ContentData contentData = getContentData(nodeRef, ContentModel.PROP_CONTENT);
|
||||
ContentData contentData = getContentData(nodeRef, propertyQName);
|
||||
|
||||
// check that the URL is available
|
||||
if (contentData == null || contentData.getContentUrl() == null)
|
||||
@@ -614,14 +627,15 @@ public class ContentServiceImpl implements ContentService, ApplicationContextAwa
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public DirectAccessUrl requestContentDirectUrl(NodeRef nodeRef, boolean attachment, Long validFor)
|
||||
@Override
|
||||
public DirectAccessUrl requestContentDirectUrl(NodeRef nodeRef, QName propertyQName, boolean attachment, Long validFor)
|
||||
{
|
||||
if (!systemWideDirectUrlConfig.isEnabled())
|
||||
{
|
||||
throw new DirectAccessUrlDisabledException("Direct access url isn't available.");
|
||||
}
|
||||
|
||||
ContentData contentData = getContentData(nodeRef, ContentModel.PROP_CONTENT);
|
||||
ContentData contentData = getContentData(nodeRef, propertyQName);
|
||||
// check that the content & URL is available
|
||||
if (contentData == null || contentData.getContentUrl() == null)
|
||||
{
|
||||
@@ -633,6 +647,7 @@ public class ContentServiceImpl implements ContentService, ApplicationContextAwa
|
||||
String fileName = getFileName(nodeRef);
|
||||
|
||||
validFor = adjustValidFor(validFor);
|
||||
attachment = adjustAttachment(nodeRef, contentMimetype, attachment);
|
||||
|
||||
DirectAccessUrl directAccessUrl = null;
|
||||
if (store.isContentDirectUrlEnabled())
|
||||
@@ -649,6 +664,38 @@ public class ContentServiceImpl implements ContentService, ApplicationContextAwa
|
||||
return directAccessUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
@Experimental
|
||||
public Map<String, String> getStorageProperties(NodeRef nodeRef, QName propertyQName)
|
||||
{
|
||||
final ContentData contentData = getContentDataOrThrowError(nodeRef, propertyQName);
|
||||
return store.getStorageProperties(contentData.getContentUrl());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean requestSendContentToArchive(NodeRef nodeRef, QName propertyQName,
|
||||
Map<String, Serializable> archiveParams)
|
||||
{
|
||||
final ContentData contentData = getContentDataOrThrowError(nodeRef, propertyQName);
|
||||
return store.requestSendContentToArchive(contentData.getContentUrl(), archiveParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean requestRestoreContentFromArchive(NodeRef nodeRef, QName propertyQName, Map<String, Serializable> restoreParams)
|
||||
{
|
||||
final ContentData contentData = getContentDataOrThrowError(nodeRef, propertyQName);
|
||||
return store.requestRestoreContentFromArchive(contentData.getContentUrl(), restoreParams);
|
||||
}
|
||||
|
||||
protected String getFileName(NodeRef nodeRef)
|
||||
{
|
||||
String fileName = null;
|
||||
@@ -672,4 +719,32 @@ public class ContentServiceImpl implements ContentService, ApplicationContextAwa
|
||||
}
|
||||
return validFor;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean adjustAttachment(NodeRef nodeRef, String mimeType, boolean attachmentIn)
|
||||
{
|
||||
boolean attachment = true;
|
||||
if (! attachmentIn)
|
||||
{
|
||||
if ((nonAttachContentTypes != null) && (nonAttachContentTypes.contains(mimeType)))
|
||||
{
|
||||
attachment = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.warn("Ignored attachment=false for " + nodeRef.getId() + " since " + mimeType + " is not in the whitelist for non-attach content types");
|
||||
}
|
||||
}
|
||||
return attachment;
|
||||
}
|
||||
|
||||
private ContentData getContentDataOrThrowError(NodeRef nodeRef, QName propertyQName)
|
||||
{
|
||||
final ContentData contentData = getContentData(nodeRef, propertyQName);
|
||||
|
||||
if (contentData == null || contentData.getContentUrl() == null)
|
||||
{
|
||||
throw new IllegalArgumentException("The supplied nodeRef " + nodeRef + " and property name: " + propertyQName + " has no content.");
|
||||
}
|
||||
return contentData;
|
||||
}
|
||||
}
|
||||
|
@@ -25,6 +25,8 @@
|
||||
*/
|
||||
package org.alfresco.repo.content.caching;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
|
||||
@@ -35,12 +37,12 @@ import org.alfresco.repo.content.caching.quota.QuotaManagerStrategy;
|
||||
import org.alfresco.repo.content.caching.quota.UnlimitedQuotaStrategy;
|
||||
import org.alfresco.repo.content.filestore.FileContentStore;
|
||||
import org.alfresco.repo.content.filestore.SpoofedTextContentReader;
|
||||
import org.alfresco.service.Experimental;
|
||||
import org.alfresco.service.cmr.repository.ContentIOException;
|
||||
import org.alfresco.service.cmr.repository.ContentReader;
|
||||
import org.alfresco.service.cmr.repository.ContentStreamListener;
|
||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
import org.alfresco.service.cmr.repository.DirectAccessUrl;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.BeanNameAware;
|
||||
@@ -67,7 +69,7 @@ public class CachingContentStore implements ContentStore, ApplicationEventPublis
|
||||
private final static Log log = LogFactory.getLog(CachingContentStore.class);
|
||||
// NUM_LOCKS absolutely must be a power of 2 for the use of locks to be evenly balanced
|
||||
private final static int numLocks = 256;
|
||||
private final static ReentrantReadWriteLock[] locks;
|
||||
private final static ReentrantReadWriteLock[] locks;
|
||||
private ContentStore backingStore;
|
||||
private ContentCache cache;
|
||||
private QuotaManagerStrategy quota = new UnlimitedQuotaStrategy();
|
||||
@@ -381,6 +383,36 @@ public class CachingContentStore implements ContentStore, ApplicationEventPublis
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
@Experimental
|
||||
public Map<String, String> getStorageProperties(final String contentUrl)
|
||||
{
|
||||
return backingStore.getStorageProperties(contentUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
@Experimental
|
||||
public boolean requestSendContentToArchive(String contentUrl, Map<String, Serializable> archiveParams)
|
||||
{
|
||||
return backingStore.requestSendContentToArchive(contentUrl, archiveParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
@Experimental
|
||||
public boolean requestRestoreContentFromArchive(String contentUrl, Map<String, Serializable> restoreParams)
|
||||
{
|
||||
return backingStore.requestRestoreContentFromArchive(contentUrl, restoreParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a ReentrantReadWriteLock for a given URL. The lock is from a pool rather than
|
||||
* per URL, so some contention is expected.
|
||||
|
@@ -25,7 +25,11 @@
|
||||
*/
|
||||
package org.alfresco.repo.content.replication;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
@@ -36,11 +40,11 @@ import org.alfresco.repo.content.ContentContext;
|
||||
import org.alfresco.repo.content.ContentStore;
|
||||
import org.alfresco.repo.content.UnsupportedContentUrlException;
|
||||
import org.alfresco.repo.content.caching.CachingContentStore;
|
||||
import org.alfresco.service.Experimental;
|
||||
import org.alfresco.service.cmr.repository.ContentIOException;
|
||||
import org.alfresco.service.cmr.repository.ContentReader;
|
||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
import org.alfresco.service.cmr.repository.DirectAccessUrl;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
@@ -64,9 +68,12 @@ import org.apache.commons.logging.LogFactory;
|
||||
* @see CachingContentStore
|
||||
*/
|
||||
public class AggregatingContentStore extends AbstractContentStore
|
||||
{
|
||||
{
|
||||
private static final Log logger = LogFactory.getLog(AggregatingContentStore.class);
|
||||
|
||||
public static final String REPLICATING_CONTENT_STORE_NOT_INITIALISED = "ReplicatingContentStore not initialised";
|
||||
public static final String SECONDARY_STORE_COULD_NOT_HANDLE_CONTENT_URL = "Secondary store %s could not handle content URL: %s";
|
||||
public static final String PRIMARY_STORE_COULD_NOT_HANDLE_CONTENT_URL = "Primary store could not handle content URL: %s";
|
||||
|
||||
private ContentStore primaryStore;
|
||||
private List<ContentStore> secondaryStores;
|
||||
|
||||
@@ -132,11 +139,8 @@ public class AggregatingContentStore extends AbstractContentStore
|
||||
*/
|
||||
public ContentReader getReader(String contentUrl) throws ContentIOException
|
||||
{
|
||||
if (primaryStore == null)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("ReplicatingContentStore not initialised");
|
||||
}
|
||||
|
||||
checkPrimaryStore();
|
||||
|
||||
// get a read lock so that we are sure that no replication is underway
|
||||
readLock.lock();
|
||||
try
|
||||
@@ -171,10 +175,7 @@ public class AggregatingContentStore extends AbstractContentStore
|
||||
|
||||
public boolean exists(String contentUrl)
|
||||
{
|
||||
if (primaryStore == null)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("ReplicatingContentStore not initialised");
|
||||
}
|
||||
checkPrimaryStore();
|
||||
|
||||
// get a read lock so that we are sure that no replication is underway
|
||||
readLock.lock();
|
||||
@@ -243,7 +244,7 @@ public class AggregatingContentStore extends AbstractContentStore
|
||||
{
|
||||
// get the writer
|
||||
ContentWriter writer = primaryStore.getWriter(ctx);
|
||||
|
||||
|
||||
return writer;
|
||||
}
|
||||
|
||||
@@ -319,10 +320,7 @@ public class AggregatingContentStore extends AbstractContentStore
|
||||
|
||||
public DirectAccessUrl requestContentDirectUrl(String contentUrl, boolean attachment, String fileName, String mimetype, Long validFor)
|
||||
{
|
||||
if (primaryStore == null)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("ReplicatingContentStore not initialised");
|
||||
}
|
||||
checkPrimaryStore();
|
||||
|
||||
// get a read lock so that we are sure that no replication is underway
|
||||
readLock.lock();
|
||||
@@ -400,4 +398,171 @@ public class AggregatingContentStore extends AbstractContentStore
|
||||
readLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
@Experimental
|
||||
public Map<String, String> getStorageProperties(String contentUrl)
|
||||
{
|
||||
checkPrimaryStore();
|
||||
|
||||
// get a read lock so that we are sure that no replication is underway
|
||||
readLock.lock();
|
||||
try
|
||||
{
|
||||
Optional<Map<String, String>> objectStoragePropertiesMap = Optional.empty();
|
||||
// Check the primary store
|
||||
try
|
||||
{
|
||||
objectStoragePropertiesMap = Optional.of(primaryStore.getStorageProperties(contentUrl));
|
||||
}
|
||||
catch (UnsupportedContentUrlException e)
|
||||
{
|
||||
final String message = String.format(PRIMARY_STORE_COULD_NOT_HANDLE_CONTENT_URL, contentUrl);
|
||||
logger.trace(message);
|
||||
}
|
||||
|
||||
if (objectStoragePropertiesMap.isEmpty() ||
|
||||
objectStoragePropertiesMap.get().isEmpty()) {// the content is not in the primary store so we have to go looking for it
|
||||
for (ContentStore store : secondaryStores)
|
||||
{
|
||||
try
|
||||
{
|
||||
objectStoragePropertiesMap = Optional.of(store.getStorageProperties(contentUrl));
|
||||
}
|
||||
catch (UnsupportedContentUrlException e)
|
||||
{
|
||||
final String message = String.format(SECONDARY_STORE_COULD_NOT_HANDLE_CONTENT_URL, store, contentUrl);
|
||||
logger.trace(message);
|
||||
}
|
||||
|
||||
if (objectStoragePropertiesMap.isPresent())
|
||||
{
|
||||
return objectStoragePropertiesMap.get();
|
||||
}
|
||||
}
|
||||
throw new UnsupportedContentUrlException(this, contentUrl);
|
||||
}
|
||||
return objectStoragePropertiesMap.orElse(Collections.emptyMap());
|
||||
|
||||
}
|
||||
finally
|
||||
{
|
||||
readLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Experimental
|
||||
@Override
|
||||
public boolean requestSendContentToArchive(final String contentUrl, Map<String, Serializable> archiveParams)
|
||||
{
|
||||
return callContentArchiveRequest(contentUrl, archiveParams, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Experimental
|
||||
@Override
|
||||
public boolean requestRestoreContentFromArchive(final String contentUrl, final Map<String, Serializable> restoreParams)
|
||||
{
|
||||
return callContentArchiveRequest(contentUrl, restoreParams, true);
|
||||
}
|
||||
|
||||
private boolean callContentArchiveRequest(final String contentUrl, final Map<String, Serializable> requestParams, final boolean restore)
|
||||
{
|
||||
checkPrimaryStore();
|
||||
// get a read lock so that we are sure that no replication is underway
|
||||
readLock.lock();
|
||||
boolean archiveRequestSucceeded = false;
|
||||
boolean primaryContentUrlUnsupported = false;
|
||||
boolean secondaryContentUrlUnsupported = false;
|
||||
try
|
||||
{
|
||||
// Check the primary store
|
||||
try
|
||||
{
|
||||
archiveRequestSucceeded = archiveRequestResult(contentUrl, requestParams, restore, primaryStore);
|
||||
}
|
||||
catch (UnsupportedOperationException e)
|
||||
{
|
||||
final String message = String.format("Primary store does not handle this operation for content URL: %s", contentUrl);
|
||||
logger.trace(message);
|
||||
}
|
||||
catch (UnsupportedContentUrlException e) {
|
||||
final String message = String.format(PRIMARY_STORE_COULD_NOT_HANDLE_CONTENT_URL, contentUrl);
|
||||
logger.trace(message);
|
||||
primaryContentUrlUnsupported = true;
|
||||
}
|
||||
|
||||
if (archiveRequestSucceeded)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{ // the content is not in the primary store so we have to go looking for it
|
||||
for (ContentStore store : secondaryStores)
|
||||
{
|
||||
try
|
||||
{
|
||||
archiveRequestSucceeded = archiveRequestResult(contentUrl, requestParams, restore, store);
|
||||
} catch (UnsupportedOperationException e)
|
||||
{
|
||||
final String message =
|
||||
String.format("Secondary store %s does not handle this operation for content URL: %s", store,
|
||||
contentUrl);
|
||||
logger.trace(message);
|
||||
}
|
||||
catch (UnsupportedContentUrlException e)
|
||||
{
|
||||
secondaryContentUrlUnsupported = true;
|
||||
final String message = String.format(SECONDARY_STORE_COULD_NOT_HANDLE_CONTENT_URL, store, contentUrl);
|
||||
logger.trace(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (archiveRequestSucceeded)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (primaryContentUrlUnsupported || secondaryContentUrlUnsupported)
|
||||
{
|
||||
return callSuperMethod(contentUrl, requestParams, restore);
|
||||
}
|
||||
|
||||
return callSuperMethod(contentUrl, requestParams, restore);
|
||||
}
|
||||
finally
|
||||
{
|
||||
readLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean callSuperMethod(String contentUrl, Map<String, Serializable> requestParams, boolean restore)
|
||||
{
|
||||
return restore ?
|
||||
super.requestRestoreContentFromArchive(contentUrl, requestParams) :
|
||||
super.requestSendContentToArchive(contentUrl, requestParams);
|
||||
}
|
||||
|
||||
private boolean archiveRequestResult(String contentUrl, Map<String, Serializable> requestParams, boolean restore,
|
||||
ContentStore store)
|
||||
{
|
||||
return restore ?
|
||||
store.requestRestoreContentFromArchive(contentUrl, requestParams) :
|
||||
store.requestSendContentToArchive(contentUrl, requestParams);
|
||||
}
|
||||
|
||||
private void checkPrimaryStore()
|
||||
{
|
||||
if (primaryStore == null)
|
||||
{
|
||||
throw new AlfrescoRuntimeException(REPLICATING_CONTENT_STORE_NOT_INITIALISED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -2,7 +2,7 @@
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2019 Alfresco Software Limited
|
||||
* Copyright (C) 2005 - 2021 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
@@ -34,6 +34,7 @@ import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.transform.client.model.config.SupportedSourceAndTarget;
|
||||
import org.alfresco.transform.client.model.config.TransformOption;
|
||||
import org.alfresco.transform.client.model.config.Transformer;
|
||||
import org.alfresco.transform.client.registry.AbstractTransformRegistry;
|
||||
import org.alfresco.transform.client.registry.CombinedConfig;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -52,7 +53,8 @@ import java.util.Set;
|
||||
* any mimetype starting "text/", or "application/x-javascript", or "application/dita+xml". There must be no transform
|
||||
* options, but in case of the text transform the source and target encodings may be change.
|
||||
*
|
||||
* Supported transforms are added by {@link CombinedConfig#addPassThroughTransformer(org.alfresco.service.cmr.repository.MimetypeService)}.
|
||||
* Supported transforms are added by {@link CombinedConfig#addPassThroughTransformer(
|
||||
* org.alfresco.service.cmr.repository.MimetypeService, AbstractTransformRegistry)}.
|
||||
*
|
||||
* @author adavis
|
||||
*/
|
||||
@@ -76,10 +78,18 @@ public class LocalPassThroughTransform extends AbstractLocalTransform
|
||||
Set<SupportedSourceAndTarget> supportedSourceAndTargetList = new HashSet();
|
||||
for (String mimetype: mimetypes)
|
||||
{
|
||||
supportedSourceAndTargetList.add(new SupportedSourceAndTarget(mimetype, mimetype, -1, 20));
|
||||
supportedSourceAndTargetList.add(SupportedSourceAndTarget.builder()
|
||||
.withSourceMediaType(mimetype)
|
||||
.withTargetMediaType(mimetype)
|
||||
.withPriority(20)
|
||||
.build());
|
||||
if (isToText(mimetype, mimetype))
|
||||
{
|
||||
supportedSourceAndTargetList.add(new SupportedSourceAndTarget(mimetype, MimetypeMap.MIMETYPE_TEXT_PLAIN, -1, 20));
|
||||
supportedSourceAndTargetList.add(SupportedSourceAndTarget.builder()
|
||||
.withSourceMediaType(mimetype)
|
||||
.withTargetMediaType(MimetypeMap.MIMETYPE_TEXT_PLAIN)
|
||||
.withPriority(20)
|
||||
.build());
|
||||
}
|
||||
}
|
||||
return Transformer.builder().withTransformerName(LocalPassThroughTransform.NAME).
|
||||
|
@@ -26,7 +26,6 @@
|
||||
package org.alfresco.repo.content.transform;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
@@ -34,6 +33,7 @@ import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.alfresco.service.cmr.repository.MimetypeService;
|
||||
import org.alfresco.transform.client.model.config.TransformOptionGroup;
|
||||
@@ -133,15 +133,15 @@ public class LocalTransformServiceRegistry extends TransformServiceRegistryImpl
|
||||
@Override
|
||||
public boolean readConfig() throws IOException
|
||||
{
|
||||
CombinedConfig combinedConfig = new CombinedConfig(getLog());
|
||||
List<String> urls = getTEngineUrls();
|
||||
CombinedConfig combinedConfig = new CombinedConfig(getLog(), this);
|
||||
List<String> urls = getTEngineUrlsSortedByName();
|
||||
boolean successReadingConfig = combinedConfig.addRemoteConfig(urls, "T-Engine");
|
||||
successReadingConfig &= combinedConfig.addLocalConfig("alfresco/transforms");
|
||||
if (pipelineConfigDir != null && !pipelineConfigDir.isBlank())
|
||||
{
|
||||
successReadingConfig &= combinedConfig.addLocalConfig(pipelineConfigDir);
|
||||
}
|
||||
combinedConfig.addPassThroughTransformer(mimetypeService);
|
||||
combinedConfig.addPassThroughTransformer(mimetypeService, this);
|
||||
combinedConfig.register(this);
|
||||
return successReadingConfig;
|
||||
}
|
||||
@@ -159,8 +159,8 @@ public class LocalTransformServiceRegistry extends TransformServiceRegistryImpl
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(Transformer transformer, Map<String, Set<TransformOption>> transformOptions,
|
||||
String baseUrl, String readFrom)
|
||||
protected void register(Transformer transformer, Map<String, Set<TransformOption>> transformOptions,
|
||||
String baseUrl, String readFrom)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -321,30 +321,23 @@ public class LocalTransformServiceRegistry extends TransformServiceRegistryImpl
|
||||
return log;
|
||||
}
|
||||
|
||||
private List<String> getTEngineUrls()
|
||||
/**
|
||||
* @return urls from System or Alfresco global properties that match of localTransform.<name>.url=<url> sorted
|
||||
* in <name> order.
|
||||
*/
|
||||
List<String> getTEngineUrlsSortedByName()
|
||||
{
|
||||
List<String> urls = new ArrayList<>();
|
||||
for (Object o : getKeySet())
|
||||
{
|
||||
if (o instanceof String)
|
||||
{
|
||||
String key = (String)o;
|
||||
if (key.startsWith(LOCAL_TRANSFORMER) && key.endsWith(URL))
|
||||
{
|
||||
Object url = getProperty(key, null);
|
||||
if (url instanceof String)
|
||||
{
|
||||
String urlStr = ((String)url).trim();
|
||||
if (!urlStr.isEmpty())
|
||||
{
|
||||
urls.add((String) url);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return urls;
|
||||
// T-Engines are sorted by name so they are in the same order as in the all-in-one transformer and the
|
||||
// T-Router. See AIOCustomConfig#getTEnginesSortedByName and TransformersConfigRegistry#retrieveRemoteConfig.
|
||||
return getKeySet().stream()
|
||||
.filter(key -> key instanceof String)
|
||||
.filter(key -> key.startsWith(LOCAL_TRANSFORMER) && key.endsWith(URL))
|
||||
.sorted()
|
||||
.map(key -> getProperty(key, null))
|
||||
.filter(url -> url instanceof String)
|
||||
.map(url -> url.trim())
|
||||
.filter(url -> !url.isEmpty())
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private int getStartupRetryPeriodSeconds(String name)
|
||||
|
@@ -415,12 +415,13 @@ implements TenantDeployer, DictionaryListener, /*TenantDictionaryListener, */Mes
|
||||
|
||||
for (NodeRef messageResource : nodeRefs)
|
||||
{
|
||||
String resourceName = (String) nodeService.getProperty(messageResource, ContentModel.PROP_NAME);
|
||||
|
||||
String bundleBaseName = messageService.getBaseBundleName(resourceName);
|
||||
String messageResourcePath = nodeService.getPath(messageResource).toPrefixString(namespaceService);
|
||||
String bundleBasePrefixedName = messageResourcePath.substring(messageResourcePath.lastIndexOf("/"));
|
||||
String bundleBaseName = messageService.getBaseBundleName(bundleBasePrefixedName);
|
||||
|
||||
if (!resourceBundleBaseNames.contains(bundleBaseName))
|
||||
{
|
||||
messageService.registerResourceBundle(storeRef.toString() + repositoryLocation.getPath() + bundleBaseName);
|
||||
resourceBundleBaseNames.add(bundleBaseName);
|
||||
}
|
||||
}
|
||||
|
@@ -2,7 +2,7 @@
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
||||
* Copyright (C) 2005 - 2021 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
@@ -33,7 +33,7 @@ import org.alfresco.service.cmr.remoteconnector.RemoteConnectorRequest;
|
||||
import org.alfresco.service.cmr.remoteconnector.RemoteConnectorResponse;
|
||||
import org.alfresco.service.cmr.remoteconnector.RemoteConnectorService;
|
||||
import org.apache.commons.httpclient.Header;
|
||||
import org.apache.tika.io.IOUtils;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
|
||||
/**
|
||||
|
@@ -2,7 +2,7 @@
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
||||
* Copyright (C) 2005 - 2021 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
@@ -683,6 +683,7 @@ public class RenditionServiceImpl implements
|
||||
log.debug("OnContentUpdate calling RenditionService2.render(\""+sourceNodeRef+"\", \""+renditionName+"\" so we switch to the new service.");
|
||||
}
|
||||
useRenditionService2 = true;
|
||||
renditionService2.clearRenditionContentData(sourceNodeRef, renditionName);
|
||||
renditionService2.render(sourceNodeRef, renditionName);
|
||||
}
|
||||
}
|
||||
|
@@ -2,7 +2,7 @@
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2020 Alfresco Software Limited
|
||||
* Copyright (C) 2005 - 2021 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
@@ -538,9 +538,8 @@ public class RenditionService2Impl implements RenditionService2, InitializingBea
|
||||
}
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Set rendition hashcode " + transformContentHashCode + " and ThumbnailLastModified for " + renditionName);
|
||||
logger.debug("Set ThumbnailLastModified for " + renditionName);
|
||||
}
|
||||
nodeService.setProperty(renditionNode, RenditionModel.PROP_RENDITION_CONTENT_HASH_CODE, transformContentHashCode);
|
||||
setThumbnailLastModified(sourceNodeRef, renditionName);
|
||||
|
||||
if (transformInputStream != null)
|
||||
@@ -554,6 +553,11 @@ public class RenditionService2Impl implements RenditionService2, InitializingBea
|
||||
contentWriter.setEncoding(DEFAULT_ENCODING);
|
||||
ContentWriter renditionWriter = contentWriter;
|
||||
renditionWriter.putContent(transformInputStream);
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Set rendition hashcode for " + renditionName);
|
||||
}
|
||||
nodeService.setProperty(renditionNode, RenditionModel.PROP_RENDITION_CONTENT_HASH_CODE, transformContentHashCode);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -563,16 +567,7 @@ public class RenditionService2Impl implements RenditionService2, InitializingBea
|
||||
}
|
||||
else
|
||||
{
|
||||
Serializable content = nodeService.getProperty(renditionNode, PROP_CONTENT);
|
||||
if (content != null)
|
||||
{
|
||||
nodeService.removeProperty(renditionNode, PROP_CONTENT);
|
||||
nodeService.removeProperty(renditionNode, PROP_RENDITION_CONTENT_HASH_CODE);
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Cleared rendition content and hashcode");
|
||||
}
|
||||
}
|
||||
clearRenditionContentData(renditionNode);
|
||||
}
|
||||
|
||||
if (!sourceHasAspectRenditioned)
|
||||
@@ -736,6 +731,43 @@ public class RenditionService2Impl implements RenditionService2, InitializingBea
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears source nodeRef rendition content and content hash code using supplied rendition name
|
||||
*
|
||||
* @param sourceNodeRef
|
||||
* @param renditionName
|
||||
*/
|
||||
public void clearRenditionContentData(NodeRef sourceNodeRef, String renditionName)
|
||||
{
|
||||
clearRenditionContentData(getRenditionNode(sourceNodeRef, renditionName));
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears supplied rendition node content (if exists) and content hash code
|
||||
*
|
||||
* @param renditionNode
|
||||
*/
|
||||
private void clearRenditionContentData(NodeRef renditionNode)
|
||||
{
|
||||
if (renditionNode != null)
|
||||
{
|
||||
Serializable content = nodeService.getProperty(renditionNode, PROP_CONTENT);
|
||||
if (content != null)
|
||||
{
|
||||
nodeService.removeProperty(renditionNode, PROP_CONTENT);
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Cleared rendition content");
|
||||
}
|
||||
}
|
||||
nodeService.removeProperty(renditionNode, PROP_RENDITION_CONTENT_HASH_CODE);
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Cleared rendition hashcode");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method checks whether the specified source node is of a content class which has been registered for
|
||||
* rendition prevention.
|
||||
@@ -886,6 +918,7 @@ public class RenditionService2Impl implements RenditionService2, InitializingBea
|
||||
RenditionDefinition2 renditionDefinition = renditionDefinitionRegistry2.getRenditionDefinition(renditionName);
|
||||
if (renditionDefinition != null)
|
||||
{
|
||||
clearRenditionContentData(sourceNodeRef, renditionName);
|
||||
render(sourceNodeRef, renditionName);
|
||||
}
|
||||
else
|
||||
|
@@ -1,51 +1,53 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco 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 Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2021 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco 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 Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.repo.tenant;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
|
||||
|
||||
import org.alfresco.repo.content.AbstractRoutingContentStore;
|
||||
import org.alfresco.repo.content.ContentContext;
|
||||
import org.alfresco.repo.content.ContentStore;
|
||||
import org.alfresco.repo.domain.tenant.TenantAdminDAO;
|
||||
import org.alfresco.repo.domain.tenant.TenantEntity;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.tenant.TenantUtil.TenantRunAsWork;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||
import org.alfresco.service.transaction.TransactionService;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
|
||||
|
||||
import org.alfresco.repo.content.AbstractRoutingContentStore;
|
||||
import org.alfresco.repo.content.ContentContext;
|
||||
import org.alfresco.repo.content.ContentStore;
|
||||
import org.alfresco.repo.domain.tenant.TenantAdminDAO;
|
||||
import org.alfresco.repo.domain.tenant.TenantEntity;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.tenant.TenantUtil.TenantRunAsWork;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||
import org.alfresco.service.Experimental;
|
||||
import org.alfresco.service.transaction.TransactionService;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
|
||||
/**
|
||||
* Content Store that supports tenant routing, if multi-tenancy is enabled.
|
||||
@@ -270,6 +272,36 @@ public abstract class AbstractTenantRoutingContentStore extends AbstractRoutingC
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Experimental
|
||||
@Override
|
||||
public Map<String, String> getStorageProperties(String contentUrl)
|
||||
{
|
||||
return getTenantContentStore().getStorageProperties(contentUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
@Experimental
|
||||
public boolean requestSendContentToArchive(String contentUrl, Map<String, Serializable> archiveParams)
|
||||
{
|
||||
return getTenantContentStore().requestSendContentToArchive(contentUrl, archiveParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
@Experimental
|
||||
public boolean requestRestoreContentFromArchive(String contentUrl, Map<String, Serializable> restoreParams)
|
||||
{
|
||||
return getTenantContentStore().requestRestoreContentFromArchive(contentUrl, restoreParams);
|
||||
}
|
||||
|
||||
protected abstract ContentStore initContentStore(ApplicationContext ctx, String contentRoot);
|
||||
}
|
||||
|
@@ -2,7 +2,7 @@
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2017 Alfresco Software Limited
|
||||
* Copyright (C) 2005 - 2021 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
@@ -640,7 +640,7 @@ public class ThumbnailServiceImpl implements ThumbnailService,
|
||||
boolean valid = true;
|
||||
ContentData content = (ContentData) this.nodeService.getProperty(thumbnailNode, ContentModel.PROP_CONTENT);
|
||||
// (MNT-17162) A thumbnail with an empty content is cached for post-transaction removal, to prevent the delete in read-only transactions.
|
||||
if (content.getSize() == 0)
|
||||
if (content == null || content.getSize() == 0)
|
||||
{
|
||||
TransactionalResourceHelper.getSet(THUMBNAIL_TO_DELETE_NODES).add(thumbnailNode);
|
||||
TransactionSupportUtil.bindListener(this.thumbnailsToDeleteTransactionListener, 0);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user