Compare commits
9 Commits
Author | SHA1 | Date | |
---|---|---|---|
dbf5881b3b | |||
8870ade2d7 | |||
af8025237b | |||
f7d74a082c | |||
2cf1b241f3 | |||
e437234c28 | |||
5d172e234e | |||
185047e755 | |||
188059e0f3 |
30
README.md
30
README.md
@@ -13,20 +13,24 @@ You can install this like any JAR extension. It just needs to be put in the web
|
|||||||
|
|
||||||
There are several configuration properties available to shape how this extension shares models in your APS installation.
|
There are several configuration properties available to shape how this extension shares models in your APS installation.
|
||||||
|
|
||||||
| Property | Default | Purpose |
|
| Property | Default | Purpose |
|
||||||
| -------------------------------------------------------- | ------- | ------- |
|
| -------------------------------------------------------- | -------- | ------- |
|
||||||
| `inteligr8.modelShareExtension.groups.canRead` | | What groups should be granted read permission to models of all types. |
|
| `inteligr8.modelShareExtension.enabled` | `true` | Enablement; `false` will disable all the behaviors of this extension. |
|
||||||
| `inteligr8.modelShareExtension.groups.canWrite` | | What groups should be granted write permission to models of all types. |
|
| `inteligr8.modelShareExtension.scanDelayInMillis` | `30000` | The delay before the first scan for all models to share. |
|
||||||
| `inteligr8.modelShareExtension.groups.canReadApps` | | What groups should be granted read permission to App models. |
|
| `inteligr8.modelShareExtension.scanIntervalInMillis` | `600000` | The interval between scans for all models to share. |
|
||||||
| `inteligr8.modelShareExtension.groups.canWriteApps` | | What groups should be granted write permission to App models. |
|
| `inteligr8.modelShareExtension.groups.canRead` | | What groups should be granted read permission to models of all types. |
|
||||||
| `inteligr8.modelShareExtension.groups.canReadProcesses` | | What groups should be granted read permission to Process models. |
|
| `inteligr8.modelShareExtension.groups.canWrite` | | What groups should be granted write permission to models of all types. |
|
||||||
| `inteligr8.modelShareExtension.groups.canWriteProcesses` | | What groups should be granted write permission to Process models. |
|
| `inteligr8.modelShareExtension.groups.canReadApps` | | What groups should be granted read permission to App models. |
|
||||||
| `inteligr8.modelShareExtension.groups.canReadForms` | | What groups should be granted read permission to Form models. |
|
| `inteligr8.modelShareExtension.groups.canWriteApps` | | What groups should be granted write permission to App models. |
|
||||||
| `inteligr8.modelShareExtension.groups.canWriteForms` | | What groups should be granted write permission to Form models. |
|
| `inteligr8.modelShareExtension.groups.canReadProcesses` | | What groups should be granted read permission to Process models. |
|
||||||
| `inteligr8.modelShareExtension.shareAllModelsOnStartup` | `false` | Set to `true` to perform a startup scanning of models, sharing them according to the configuration. |
|
| `inteligr8.modelShareExtension.groups.canWriteProcesses` | | What groups should be granted write permission to Process models. |
|
||||||
| `inteligr8.modelShareExtension.modelChunkSize` | `50` | When querying for all models, how many models should be queried per page. |
|
| `inteligr8.modelShareExtension.groups.canReadForms` | | What groups should be granted read permission to Form models. |
|
||||||
| `inteligr8.modelShareExtension.shareChunkSize` | `20` | When querying all user/group share permissions on a single model, how many records should be queried per page. |
|
| `inteligr8.modelShareExtension.groups.canWriteForms` | | What groups should be granted write permission to Form models. |
|
||||||
|
| `inteligr8.modelShareExtension.modelChunkSize` | `50` | When querying for all models, how many models should be queried per page. |
|
||||||
|
| `inteligr8.modelShareExtension.shareChunkSize` | `25` | When querying all user/group share permissions on a single model, how many records should be queried per page. |
|
||||||
|
|
||||||
You can specify these at startup as JVM system properties.
|
You can specify these at startup as JVM system properties.
|
||||||
|
|
||||||
When specifying groups, use commas to separate each entry. You can also prefix each group with "sys:" or "org:" to target a specific system or organizational/functional group. The extension will query by group name and then external ID in each case.
|
When specifying groups, use commas to separate each entry. You can also prefix each group with "sys:" or "org:" to target a specific system or organizational/functional group. The extension will query by group name and then external ID in each case.
|
||||||
|
|
||||||
|
Any specification of a specific group permission (e.g. `canReadApps`) will override any specification for the same group in the generic `canRead` or `canWrite` property.
|
||||||
|
10
pom.xml
10
pom.xml
@@ -39,11 +39,11 @@
|
|||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<maven.compiler.source>11</maven.compiler.source>
|
<maven.compiler.source>17</maven.compiler.source>
|
||||||
<maven.compiler.target>11</maven.compiler.target>
|
<maven.compiler.target>17</maven.compiler.target>
|
||||||
<maven.compiler.release>11</maven.compiler.release>
|
<maven.compiler.release>17</maven.compiler.release>
|
||||||
|
|
||||||
<aps.version>2.4.1</aps.version>
|
<aps.version>24.3.0</aps.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
@@ -154,7 +154,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.sonatype.plugins</groupId>
|
<groupId>org.sonatype.plugins</groupId>
|
||||||
<artifactId>nexus-staging-maven-plugin</artifactId>
|
<artifactId>nexus-staging-maven-plugin</artifactId>
|
||||||
<version>1.6.13</version>
|
<version>1.7.0</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<serverId>ossrh</serverId>
|
<serverId>ossrh</serverId>
|
||||||
<nexusUrl>https://s01.oss.sonatype.org/</nexusUrl>
|
<nexusUrl>https://s01.oss.sonatype.org/</nexusUrl>
|
||||||
|
@@ -17,6 +17,7 @@ package com.activiti.extension.conf;
|
|||||||
import org.springframework.context.annotation.ComponentScan;
|
import org.springframework.context.annotation.ComponentScan;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.FullyQualifiedAnnotationBeanNameGenerator;
|
import org.springframework.context.annotation.FullyQualifiedAnnotationBeanNameGenerator;
|
||||||
|
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A means for injecting packages to scan for the Spring context.
|
* A means for injecting packages to scan for the Spring context.
|
||||||
@@ -24,6 +25,7 @@ import org.springframework.context.annotation.FullyQualifiedAnnotationBeanNameGe
|
|||||||
* @author brian@inteligr8.com
|
* @author brian@inteligr8.com
|
||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
|
@EnableScheduling
|
||||||
@ComponentScan(
|
@ComponentScan(
|
||||||
basePackages = "com.inteligr8.alfresco.activiti.share",
|
basePackages = "com.inteligr8.alfresco.activiti.share",
|
||||||
nameGenerator = FullyQualifiedAnnotationBeanNameGenerator.class
|
nameGenerator = FullyQualifiedAnnotationBeanNameGenerator.class
|
||||||
|
@@ -1,33 +0,0 @@
|
|||||||
/*
|
|
||||||
* This program 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.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package com.inteligr8.alfresco.activiti.share;
|
|
||||||
|
|
||||||
import org.activiti.engine.delegate.event.ActivitiEntityEvent;
|
|
||||||
import org.activiti.engine.delegate.event.ActivitiEvent;
|
|
||||||
import org.activiti.engine.delegate.event.ActivitiEventListener;
|
|
||||||
import org.activiti.engine.delegate.event.ActivitiEventType;
|
|
||||||
import org.activiti.engine.impl.persistence.entity.Entity;
|
|
||||||
|
|
||||||
public interface ActivitiEntityEventListener extends ActivitiEventListener {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
default void onEvent(ActivitiEvent event) {
|
|
||||||
ActivitiEntityEvent eevent = (ActivitiEntityEvent) event;
|
|
||||||
this.onEntityEvent(event.getType(), (Entity) eevent.getEntity());
|
|
||||||
}
|
|
||||||
|
|
||||||
void onEntityEvent(ActivitiEventType eventType, Entity entity);
|
|
||||||
|
|
||||||
}
|
|
@@ -1,61 +0,0 @@
|
|||||||
/*
|
|
||||||
* This program 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.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package com.inteligr8.alfresco.activiti.share;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.activiti.engine.ProcessEngine;
|
|
||||||
import org.activiti.engine.delegate.event.ActivitiEvent;
|
|
||||||
import org.activiti.engine.repository.Model;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
public class EngineStartEventListener extends NoFailActivitiEventListener {
|
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
|
||||||
|
|
||||||
@Value("${inteligr8.modelShareExtension.modelChunkSize:50}")
|
|
||||||
private int modelChunkSize;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private ProcessEngine services;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private ModelShareWorker shareWorker;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onEvent(ActivitiEvent event) {
|
|
||||||
this.logger.info("Starting to query all models to share all of them");
|
|
||||||
|
|
||||||
int page = 1;
|
|
||||||
int perPage = this.modelChunkSize;
|
|
||||||
|
|
||||||
List<Model> models = this.services.getRepositoryService().createModelQuery().listPage((page-1)*perPage, perPage);
|
|
||||||
while (!models.isEmpty()) {
|
|
||||||
for (Model model : models) {
|
|
||||||
this.logger.debug("Discovered model: {}: {}: {}", model.getCategory(), model.getId(), model.getName());
|
|
||||||
this.shareWorker.share(model);
|
|
||||||
}
|
|
||||||
|
|
||||||
page++;
|
|
||||||
models = this.services.getRepositoryService().createModelQuery().listPage((page-1)*perPage, perPage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -1,55 +0,0 @@
|
|||||||
/*
|
|
||||||
* This program 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.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package com.inteligr8.alfresco.activiti.share;
|
|
||||||
|
|
||||||
import org.activiti.engine.delegate.event.ActivitiEventType;
|
|
||||||
import org.activiti.engine.impl.persistence.entity.Entity;
|
|
||||||
import org.activiti.engine.impl.persistence.entity.ModelEntity;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
public class ModelEntityEventListener extends NoFailActivitiEventListener implements ActivitiEntityEventListener {
|
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private ModelShareWorker shareWorker;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onEntityEvent(ActivitiEventType eventType, Entity entity) {
|
|
||||||
this.validate(eventType);
|
|
||||||
|
|
||||||
if (entity instanceof ModelEntity) {
|
|
||||||
ModelEntity mentity = (ModelEntity) entity;
|
|
||||||
this.logger.debug("Caught model event: {}: {}: {}: {}", mentity.getCategory(), entity.getId(), mentity.getKey(), mentity.getName());
|
|
||||||
this.shareWorker.share(mentity);
|
|
||||||
} else {
|
|
||||||
this.logger.trace("Ignoring entity type: {}", entity.getClass());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void validate(ActivitiEventType eventType) {
|
|
||||||
switch (eventType) {
|
|
||||||
case ENTITY_CREATED:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new IllegalArgumentException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -14,57 +14,69 @@
|
|||||||
*/
|
*/
|
||||||
package com.inteligr8.alfresco.activiti.share;
|
package com.inteligr8.alfresco.activiti.share;
|
||||||
|
|
||||||
import org.activiti.engine.ProcessEngine;
|
|
||||||
import org.activiti.engine.delegate.event.ActivitiEventType;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import com.activiti.domain.idm.User;
|
||||||
|
import com.activiti.security.SecurityUtils;
|
||||||
|
import com.activiti.service.api.UserService;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class ModelShareExtension implements Bootstrappable {
|
public class ModelShareExtension implements Bootstrappable {
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ProcessEngine services;
|
private ModelShareWorker worker;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ModelEntityEventListener entityListener;
|
private UserService userService;
|
||||||
|
|
||||||
@Autowired
|
@Value("${inteligr8.modelShareExtension.runAs:admin@app.activiti.com}")
|
||||||
private EngineStartEventListener startupListener;
|
private String runAsUser;
|
||||||
|
|
||||||
/**
|
@Value("${inteligr8.modelShareExtension.enabled:true}")
|
||||||
* On startup, scan all models and share them according to the configuration defined elsewhere.
|
private boolean enabled;
|
||||||
*/
|
|
||||||
@Value("${inteligr8.modelShareExtension.shareAllModelsOnStartup:false}")
|
private boolean bootstrapped;
|
||||||
private boolean shareAllModelsOnStartup;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBootstrap() {
|
public void onBootstrap() {
|
||||||
this.logger.trace("onBootstrap()");
|
this.logger.trace("onBootstrap()");
|
||||||
|
|
||||||
this.registerListeners();
|
if (!this.enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.logger.info("Model Share Extension enabled");
|
||||||
|
this.bootstrapped = true;
|
||||||
this.logger.info("Model Share Extension initialized");
|
this.logger.info("Model Share Extension initialized");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void registerListeners() {
|
public boolean isEnabled() {
|
||||||
this.logger.info("registerListeners()");
|
return this.enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
// execute every 10 minutes
|
||||||
|
@Scheduled(
|
||||||
|
fixedRateString = "${inteligr8.modelShareExtension.scanIntervalInMillis:600000}",
|
||||||
|
initialDelayString = "${inteligr8.modelShareExtension.scanDelayInMillis:30000}"
|
||||||
|
)
|
||||||
|
private void scheduled() {
|
||||||
|
if (!this.enabled || !this.bootstrapped)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.logger.trace("scheduled()");
|
||||||
|
|
||||||
|
this.logger.debug("Assuming user: {}", this.runAsUser);
|
||||||
|
User runAsUser = this.userService.findUserByEmail(this.runAsUser);
|
||||||
|
SecurityUtils.assumeUser(runAsUser);
|
||||||
|
this.logger.debug("Assumed user: {}", runAsUser.getId());
|
||||||
|
|
||||||
this.services.getRuntimeService().addEventListener(
|
this.worker.shareAllModels();
|
||||||
this.entityListener,
|
|
||||||
ActivitiEventType.ENTITY_CREATED);
|
|
||||||
|
|
||||||
if (this.shareAllModelsOnStartup) {
|
|
||||||
// we can't use ENGINE_CREATED as it has already been created
|
|
||||||
this.services.getRuntimeService().addEventListener(
|
|
||||||
this.startupListener,
|
|
||||||
ActivitiEventType.ENGINE_CREATED);
|
|
||||||
this.startupListener.onEvent(null);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -24,6 +24,8 @@ import java.util.Map;
|
|||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.activiti.engine.ProcessEngine;
|
||||||
|
import org.activiti.engine.repository.ModelQuery;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@@ -33,6 +35,7 @@ import org.springframework.data.domain.PageRequest;
|
|||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import com.activiti.domain.editor.AbstractModel;
|
||||||
import com.activiti.domain.editor.Model;
|
import com.activiti.domain.editor.Model;
|
||||||
import com.activiti.domain.editor.ModelShareInfo;
|
import com.activiti.domain.editor.ModelShareInfo;
|
||||||
import com.activiti.domain.editor.SharePermission;
|
import com.activiti.domain.editor.SharePermission;
|
||||||
@@ -47,6 +50,9 @@ public class ModelShareWorker implements Bootstrappable {
|
|||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||||
|
|
||||||
|
@Value("${inteligr8.modelShareExtension.modelChunkSize:50}")
|
||||||
|
private int modelChunkSize;
|
||||||
|
|
||||||
@Value("${inteligr8.modelShareExtension.shareChunkSize:25}")
|
@Value("${inteligr8.modelShareExtension.shareChunkSize:25}")
|
||||||
private int shareChunkSize;
|
private int shareChunkSize;
|
||||||
|
|
||||||
@@ -74,6 +80,9 @@ public class ModelShareWorker implements Bootstrappable {
|
|||||||
@Value("${inteligr8.modelShareExtension.groups.canWriteForms:#{null}}")
|
@Value("${inteligr8.modelShareExtension.groups.canWriteForms:#{null}}")
|
||||||
private String writeFormDefsGroupNames;
|
private String writeFormDefsGroupNames;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ProcessEngine services;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ModelShareService shareService;
|
private ModelShareService shareService;
|
||||||
|
|
||||||
@@ -97,8 +106,8 @@ public class ModelShareWorker implements Bootstrappable {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBootstrap() {
|
public void onBootstrap() {
|
||||||
this.logger.trace("onBootstrap({})");
|
this.logger.trace("onBootstrap()");
|
||||||
|
|
||||||
this.tenantId = this.tenantService.findTenantId();
|
this.tenantId = this.tenantService.findTenantId();
|
||||||
this.groups = this.toMap(this.findGroups(this.readGroupNames), SharePermission.READ);
|
this.groups = this.toMap(this.findGroups(this.readGroupNames), SharePermission.READ);
|
||||||
this.toMap(this.groups, this.findGroups(this.writeGroupNames), SharePermission.WRITE);
|
this.toMap(this.groups, this.findGroups(this.writeGroupNames), SharePermission.WRITE);
|
||||||
@@ -199,12 +208,110 @@ public class ModelShareWorker implements Bootstrappable {
|
|||||||
map.put(key, value);
|
map.put(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void share(org.activiti.engine.repository.Model orgModel) {
|
public void shareAllModels() {
|
||||||
|
this.shareApsFormModels();
|
||||||
|
this.shareApsDataModels();
|
||||||
|
this.shareApsDecisionTableModels();
|
||||||
|
this.shareApsProcessModels();
|
||||||
|
this.shareApsAppModels();
|
||||||
|
|
||||||
|
if (this.tenantId != null) {
|
||||||
|
this.shareAllActivitiModels(this.tenantId);
|
||||||
|
} else {
|
||||||
|
this.shareAllActivitiModels(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void shareApsFormModels() {
|
||||||
|
this.logger.trace("Discovering APS form models");
|
||||||
|
List<AbstractModel> models = this.modelService.getModelsByModelTypeAndReferenceId(Model.MODEL_TYPE_FORM, null);
|
||||||
|
for (AbstractModel model : models) {
|
||||||
|
this.logger.debug("Discovered APS form model: {} [{}]", model.getName(), model.getId());
|
||||||
|
this.shareModel((Model) model);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void shareApsDataModels() {
|
||||||
|
this.logger.trace("Discovering APS data models");
|
||||||
|
List<AbstractModel> models = this.modelService.getModelsByModelTypeAndReferenceId(Model.MODEL_TYPE_DATA_MODEL, null);
|
||||||
|
for (AbstractModel model : models) {
|
||||||
|
this.logger.debug("Discovered APS data model: {} [{}]", model.getName(), model.getId());
|
||||||
|
this.shareModel((Model) model);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void shareApsDecisionTableModels() {
|
||||||
|
this.logger.trace("Discovering APS decision table models");
|
||||||
|
List<AbstractModel> models = this.modelService.getModelsByModelTypeAndReferenceId(Model.MODEL_TYPE_DECISION_TABLE, null);
|
||||||
|
for (AbstractModel model : models) {
|
||||||
|
this.logger.debug("Discovered APS decision table model: {} [{}]", model.getName(), model.getId());
|
||||||
|
this.shareModel((Model) model);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void shareApsProcessModels() {
|
||||||
|
this.logger.trace("Discovering APS process models");
|
||||||
|
List<AbstractModel> models = this.modelService.getModelsByModelTypeAndReferenceId(Model.MODEL_TYPE_BPMN, null);
|
||||||
|
for (AbstractModel model : models) {
|
||||||
|
this.logger.debug("Discovered APS process model: {} [{}]", model.getName(), model.getId());
|
||||||
|
this.shareModel((Model) model);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void shareApsAppModels() {
|
||||||
|
this.logger.trace("Discovering APS app models");
|
||||||
|
List<AbstractModel> models = this.modelService.getModelsByModelTypeAndReferenceId(Model.MODEL_TYPE_APP, null);
|
||||||
|
for (AbstractModel model : models) {
|
||||||
|
this.logger.debug("Discovered APS app model: {} [{}]", model.getName(), model.getId());
|
||||||
|
this.shareModel((Model) model);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void shareAllActivitiModels(Long tenantId) {
|
||||||
|
this.logger.trace("Discovering activiti models in tenant {} ...", tenantId);
|
||||||
|
|
||||||
|
long modelCount = 0L;
|
||||||
|
int page = 1;
|
||||||
|
int perPage = this.modelChunkSize;
|
||||||
|
|
||||||
|
ModelQuery query = this.services.getRepositoryService().createModelQuery()
|
||||||
|
.latestVersion();
|
||||||
|
if (tenantId != null)
|
||||||
|
query.modelTenantId(String.valueOf(tenantId));
|
||||||
|
else query.modelWithoutTenantId();
|
||||||
|
|
||||||
|
this.logger.trace("Discovering activiti models with page size: {}", perPage);
|
||||||
|
List<org.activiti.engine.repository.Model> models = query.listPage((page-1)*perPage, perPage);
|
||||||
|
if (models.isEmpty()) {
|
||||||
|
this.logger.debug("No activiti models; procDef count: {}", this.services.getRepositoryService().createProcessDefinitionQuery().latestVersion().count());
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!models.isEmpty()) {
|
||||||
|
this.logger.trace("Fetched page #{} of {} activiti models in tenant {}", page, models.size(), tenantId);
|
||||||
|
|
||||||
|
for (org.activiti.engine.repository.Model model : models) {
|
||||||
|
this.logger.debug("Discovered model: {}: {}: {}", model.getCategory(), model.getId(), model.getName());
|
||||||
|
this.shareModel(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
modelCount += models.size();
|
||||||
|
page++;
|
||||||
|
models = query.listPage((page-1)*perPage, perPage);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.logger.trace("Discovered {} activiti models in tenant {}", modelCount, tenantId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void shareModel(org.activiti.engine.repository.Model orgModel) {
|
||||||
Model model = (Model) this.modelService.getModel(Long.valueOf(orgModel.getId()));
|
Model model = (Model) this.modelService.getModel(Long.valueOf(orgModel.getId()));
|
||||||
|
this.shareModel(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void shareModel(Model model) {
|
||||||
Map<HashableGroup, SharePermission> shares = this.fetchCurrentModelShares(model);
|
Map<HashableGroup, SharePermission> shares = this.fetchCurrentModelShares(model);
|
||||||
|
|
||||||
switch (model.getModelType()) {
|
switch (model.getModelType()) {
|
||||||
case 3:
|
case Model.MODEL_TYPE_APP:
|
||||||
for (Entry<HashableGroup, SharePermission> group : this.groups.entrySet()) {
|
for (Entry<HashableGroup, SharePermission> group : this.groups.entrySet()) {
|
||||||
if (this.appDefsGroups.containsKey(group.getKey())) {
|
if (this.appDefsGroups.containsKey(group.getKey())) {
|
||||||
this.logger.trace("The default group permission is overridden by the app group permission: {}", group.getKey());
|
this.logger.trace("The default group permission is overridden by the app group permission: {}", group.getKey());
|
||||||
@@ -215,7 +322,7 @@ public class ModelShareWorker implements Bootstrappable {
|
|||||||
for (Entry<HashableGroup, SharePermission> group : this.appDefsGroups.entrySet())
|
for (Entry<HashableGroup, SharePermission> group : this.appDefsGroups.entrySet())
|
||||||
this.share(shares, model, group.getKey(), group.getValue());
|
this.share(shares, model, group.getKey(), group.getValue());
|
||||||
break;
|
break;
|
||||||
case 0:
|
case Model.MODEL_TYPE_BPMN:
|
||||||
for (Entry<HashableGroup, SharePermission> group : this.groups.entrySet()) {
|
for (Entry<HashableGroup, SharePermission> group : this.groups.entrySet()) {
|
||||||
if (this.processDefsGroups.containsKey(group.getKey())) {
|
if (this.processDefsGroups.containsKey(group.getKey())) {
|
||||||
this.logger.trace("The default group permission is overridden by the app group permission: {}", group.getKey());
|
this.logger.trace("The default group permission is overridden by the app group permission: {}", group.getKey());
|
||||||
@@ -226,7 +333,7 @@ public class ModelShareWorker implements Bootstrappable {
|
|||||||
for (Entry<HashableGroup, SharePermission> group : this.processDefsGroups.entrySet())
|
for (Entry<HashableGroup, SharePermission> group : this.processDefsGroups.entrySet())
|
||||||
this.share(shares, model, group.getKey(), group.getValue());
|
this.share(shares, model, group.getKey(), group.getValue());
|
||||||
break;
|
break;
|
||||||
case 1:
|
case Model.MODEL_TYPE_FORM:
|
||||||
for (Entry<HashableGroup, SharePermission> group : this.groups.entrySet()) {
|
for (Entry<HashableGroup, SharePermission> group : this.groups.entrySet()) {
|
||||||
if (this.formDefsGroups.containsKey(group.getKey())) {
|
if (this.formDefsGroups.containsKey(group.getKey())) {
|
||||||
this.logger.trace("The default group permission is overridden by the app group permission: {}", group.getKey());
|
this.logger.trace("The default group permission is overridden by the app group permission: {}", group.getKey());
|
||||||
@@ -253,9 +360,15 @@ public class ModelShareWorker implements Bootstrappable {
|
|||||||
for (ModelShareInfo share : shares)
|
for (ModelShareInfo share : shares)
|
||||||
map.put(new HashableGroup(share.getGroup()), share.getPermission());
|
map.put(new HashableGroup(share.getGroup()), share.getPermission());
|
||||||
|
|
||||||
|
pageable = pageable.next();
|
||||||
shares = this.shareInfoRepo.findByModelIdOrderByShareDateAsc(model.getId(), pageable);
|
shares = this.shareInfoRepo.findByModelIdOrderByShareDateAsc(model.getId(), pageable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.logger.isTraceEnabled()) {
|
||||||
|
this.logger.trace("Found existing shares: {}", map);
|
||||||
|
} else {
|
||||||
|
this.logger.debug("Found existing shares: {}", map.size());
|
||||||
|
}
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -268,8 +381,8 @@ public class ModelShareWorker implements Bootstrappable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void share(Model model, HashableGroup group, SharePermission permission) {
|
private void share(Model model, HashableGroup group, SharePermission permission) {
|
||||||
this.logger.debug("Sharing model with group: {}: {}: {}", model.getId(), model.getName(), group);
|
this.logger.info("Sharing model with group: {}: {}: {}", model.getId(), model.getName(), group);
|
||||||
this.shareService.shareModelWithGroup(model, group.getGroup(), permission);
|
this.shareService.shareModelWithGroup(model, group.getGroup(), permission).getShareDate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unshareAll(Model model) {
|
public void unshareAll(Model model) {
|
||||||
@@ -311,7 +424,13 @@ public class ModelShareWorker implements Bootstrappable {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
return this.group.getId().equals(((Group) obj).getId());
|
if (obj instanceof HashableGroup) {
|
||||||
|
return this.group.getId().equals(((HashableGroup) obj).getGroup().getId());
|
||||||
|
} else if (obj instanceof Group) {
|
||||||
|
return this.group.getId().equals(((Group) obj).getId());
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -1,26 +0,0 @@
|
|||||||
/*
|
|
||||||
* This program 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.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package com.inteligr8.alfresco.activiti.share;
|
|
||||||
|
|
||||||
import org.activiti.engine.delegate.event.ActivitiEventListener;
|
|
||||||
|
|
||||||
public abstract class NoFailActivitiEventListener implements ActivitiEventListener {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isFailOnException() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Reference in New Issue
Block a user