added docs; logging; prep for maven central
This commit is contained in:
parent
dd9d5735bf
commit
99d76df708
185
pom.xml
185
pom.xml
@ -1,8 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<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">
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.inteligr8.alfresco</groupId>
|
||||
@ -11,8 +10,19 @@
|
||||
<packaging>maven-plugin</packaging>
|
||||
|
||||
<name>A Maven plugin for Alfresco Process Services model portability</name>
|
||||
<description>Generate Alfresco Module Packages (AMP) files in a way simialr to WAR files</description>
|
||||
<url>https://bitbucket.org/inteligr8/amp-maven-plugin</url>
|
||||
|
||||
<licenses>
|
||||
<license>
|
||||
<name>GNU GENERAL PUBLIC LICENSE, Version 3, 29 June 2007</name>
|
||||
<url>https://www.gnu.org/licenses/lgpl-3.0.txt</url>
|
||||
</license>
|
||||
</licenses>
|
||||
|
||||
<scm>
|
||||
<connection>scm:git:https://bitbucket.org/inteligr8/aps-model-maven-plugin.git</connection>
|
||||
<developerConnection>scm:git:git@bitbucket.org:inteligr8/aps-model-maven-plugin.git</developerConnection>
|
||||
<url>https://bitbucket.org/inteligr8/aps-model-maven-plugin</url>
|
||||
</scm>
|
||||
<organization>
|
||||
@ -41,14 +51,12 @@
|
||||
<dependency>
|
||||
<groupId>com.inteligr8.alfresco</groupId>
|
||||
<artifactId>aps-public-rest-api</artifactId>
|
||||
<version>2.0.1</version>
|
||||
<classifier>aps1</classifier>
|
||||
<version>2.0.3-aps1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.inteligr8.alfresco</groupId>
|
||||
<artifactId>aps-public-rest-client</artifactId>
|
||||
<version>2.0.1</version>
|
||||
<classifier>jersey</classifier>
|
||||
<version>2.0.2-jersey</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
@ -109,10 +117,36 @@
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-invoker-plugin</artifactId>
|
||||
<version>3.2.2</version>
|
||||
<configuration>
|
||||
<projectsDirectory>${basedir}/src/it</projectsDirectory>
|
||||
<cloneProjectsTo>${project.build.directory}/it</cloneProjectsTo>
|
||||
<localRepositoryPath>${project.build.directory}/it-repo</localRepositoryPath>
|
||||
<mavenHome>${env.MAVEN_HOME}</mavenHome>
|
||||
<debug>true</debug>
|
||||
<skipInvocation>${skipTests}</skipInvocation>
|
||||
<properties>
|
||||
<project.main.basedir>${basedir}</project.main.basedir>
|
||||
<aps-model.baseUrl>${aps-model.baseUrl}</aps-model.baseUrl>
|
||||
<aps-model.authType>${aps-model.authType}</aps-model.authType>
|
||||
<aps-model.basicAuth.mavenServerId>${aps-model.basicAuth.mavenServerId}</aps-model.basicAuth.mavenServerId>
|
||||
<aps-model.appName>${aps-model.appName}</aps-model.appName>
|
||||
<aps-model.share.editors>${aps-model.share.editors}</aps-model.share.editors>
|
||||
<aps-model.share.readers>${aps-model.share.readers}</aps-model.share.readers>
|
||||
<aps-model.share.app.editors>${aps-model.share.app.editors}</aps-model.share.app.editors>
|
||||
</properties>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-plugin-plugin</artifactId>
|
||||
<version>3.6.0</version>
|
||||
<version>3.6.1</version>
|
||||
<configuration>
|
||||
<goalPrefix>aps-model</goalPrefix>
|
||||
</configuration>
|
||||
@ -143,55 +177,29 @@
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-invoker-plugin</artifactId>
|
||||
<version>3.2.2</version>
|
||||
<configuration>
|
||||
<projectsDirectory>${basedir}/src/it</projectsDirectory>
|
||||
<cloneProjectsTo>${project.build.directory}/it</cloneProjectsTo>
|
||||
<localRepositoryPath>${project.build.directory}/it-repo</localRepositoryPath>
|
||||
<mavenHome>${env.MAVEN_HOME}</mavenHome>
|
||||
<debug>true</debug>
|
||||
<skipInvocation>${skipTests}</skipInvocation>
|
||||
<properties>
|
||||
<project.main.basedir>${basedir}</project.main.basedir>
|
||||
<aps-model.baseUrl>${aps-model.baseUrl}</aps-model.baseUrl>
|
||||
<aps-model.authType>${aps-model.authType}</aps-model.authType>
|
||||
<aps-model.basicAuth.mavenServerId>${aps-model.basicAuth.mavenServerId}</aps-model.basicAuth.mavenServerId>
|
||||
<aps-model.appName>${aps-model.appName}</aps-model.appName>
|
||||
<aps-model.share.editors>${aps-model.share.editors}</aps-model.share.editors>
|
||||
<aps-model.share.readers>${aps-model.share.readers}</aps-model.share.readers>
|
||||
<aps-model.share.app.editors>${aps-model.share.app.editors}</aps-model.share.app.editors>
|
||||
</properties>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>run-its</id>
|
||||
<goals>
|
||||
<goal>install</goal>
|
||||
<goal>run</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>javadoc</id>
|
||||
<phase>package</phase>
|
||||
<goals><goal>jar</goal></goals>
|
||||
<configuration>
|
||||
<show>public</show>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>run-its</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-invoker-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>run-its</id>
|
||||
<goals>
|
||||
<goal>install</goal>
|
||||
<goal>run</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>run-it-1</id>
|
||||
<activation>
|
||||
@ -203,10 +211,9 @@
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-invoker-plugin</artifactId>
|
||||
<version>3.2.2</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>run-its</id>
|
||||
<id>run-it-1</id>
|
||||
<goals>
|
||||
<goal>install</goal>
|
||||
<goal>run</goal>
|
||||
@ -222,22 +229,56 @@
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>ossrh-release</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>source</id>
|
||||
<phase>package</phase>
|
||||
<goals><goal>jar-no-fork</goal></goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>javadoc</id>
|
||||
<phase>package</phase>
|
||||
<goals><goal>jar</goal></goals>
|
||||
<configuration>
|
||||
<show>public</show>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-gpg-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>sign</id>
|
||||
<phase>verify</phase>
|
||||
<goals><goal>sign</goal></goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.sonatype.plugins</groupId>
|
||||
<artifactId>nexus-staging-maven-plugin</artifactId>
|
||||
<version>1.6.13</version>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<serverId>ossrh</serverId>
|
||||
<nexusUrl>https://s01.oss.sonatype.org/</nexusUrl>
|
||||
<autoReleaseAfterClose>true</autoReleaseAfterClose>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>inteligr8-releases</id>
|
||||
<name>Inteligr8 Releases</name>
|
||||
<url>https://repos.inteligr8.com/nexus/repository/inteligr8-public</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<distributionManagement>
|
||||
<repository>
|
||||
<id>inteligr8-releases</id>
|
||||
<name>Inteligr8 Releases</name>
|
||||
<url>https://repos.inteligr8.com/nexus/repository/inteligr8-public</url>
|
||||
</repository>
|
||||
</distributionManagement>
|
||||
|
||||
</project>
|
||||
|
@ -1,13 +1,48 @@
|
||||
/*
|
||||
* 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.maven.aps.modeling.crawler;
|
||||
|
||||
/**
|
||||
* An interface for APS App export transformation implementations.
|
||||
*
|
||||
* An APS App export is a ZIP file that always contains an APS App JSON file.
|
||||
* It may also contain many process XML/JSON files, form JSON files, thumbnail
|
||||
* images, and more.
|
||||
*
|
||||
* @author brian@inteligr8.com
|
||||
*/
|
||||
public interface ApsAppCrawlable {
|
||||
|
||||
/**
|
||||
* @return A file transformer for APS App JSON files.
|
||||
*/
|
||||
ApsFileTransformer getAppJsonTransformer();
|
||||
|
||||
/**
|
||||
* @return A file transformer for APS Process JSON files.
|
||||
*/
|
||||
ApsFileTransformer getProcessJsonTransformer();
|
||||
|
||||
/**
|
||||
* @return A file transformer for APS Process BPMN (XML) files.
|
||||
*/
|
||||
ApsFileTransformer getProcessBpmnTransformer();
|
||||
|
||||
/**
|
||||
* @return A file transformer for APS Form JSON files.
|
||||
*/
|
||||
ApsFileTransformer getFormJsonTransformer();
|
||||
|
||||
}
|
||||
|
@ -1,3 +1,17 @@
|
||||
/*
|
||||
* 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.maven.aps.modeling.crawler;
|
||||
|
||||
import java.io.File;
|
||||
@ -11,6 +25,12 @@ import java.util.regex.Pattern;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* A class that implements a APS App export crawler. The crawler does not
|
||||
* directly perform any transformations. Those are handled through a callback.
|
||||
*
|
||||
* @author brian@inteligr8.com
|
||||
*/
|
||||
public class ApsAppCrawler {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(ApsAppCrawler.class);
|
||||
@ -20,27 +40,39 @@ public class ApsAppCrawler {
|
||||
private final File appDescriptor;
|
||||
private final boolean failOnIntegrityViolation;
|
||||
|
||||
/**
|
||||
* @param apsAppName A name for the APS App.
|
||||
* @param apsAppDirectory A directory to the unpacked APS App export.
|
||||
* @param failOnIntegrityViolation true to fail on file integrity issues; false to log warnings.
|
||||
*/
|
||||
public ApsAppCrawler(String apsAppName, File apsAppDirectory, boolean failOnIntegrityViolation) {
|
||||
this.appName = apsAppName;
|
||||
this.appDirectory = apsAppDirectory;
|
||||
this.failOnIntegrityViolation = failOnIntegrityViolation;
|
||||
|
||||
this.appDescriptor = this.validateDescriptor(appDirectory);
|
||||
this.appDescriptor = this.validateDescriptor();
|
||||
if (this.logger.isDebugEnabled())
|
||||
this.logger.debug("APS App descriptor found: " + this.appDescriptor);
|
||||
}
|
||||
|
||||
protected File validateDescriptor(File appDirectory) {
|
||||
File appDescriptor = new File(appDirectory, this.appName + ".json");
|
||||
/**
|
||||
* @return A file handle to the root APS App JSON (configuration) file.
|
||||
*/
|
||||
protected File validateDescriptor() {
|
||||
File appDescriptor = new File(this.appDirectory, this.appName + ".json");
|
||||
|
||||
if (!appDescriptor.exists())
|
||||
throw new IllegalStateException("The APS App descriptor could not be found: " + appDescriptor);
|
||||
throw new IllegalStateException("The APS App descriptor could not be found: " + this.appDescriptor);
|
||||
if (!appDescriptor.isFile())
|
||||
throw new IllegalStateException("The APS App descriptor is not a file: " + appDescriptor);
|
||||
throw new IllegalStateException("The APS App descriptor is not a file: " + this.appDescriptor);
|
||||
|
||||
return appDescriptor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param crawlable A crawlable implementation; the callback for potential transformations.
|
||||
* @throws IOException A file access exception occurred.
|
||||
*/
|
||||
public void execute(ApsAppCrawlable crawlable) throws IOException {
|
||||
this.logger.info("Crawling APS App ...");
|
||||
|
||||
@ -83,7 +115,7 @@ public class ApsAppCrawler {
|
||||
}
|
||||
|
||||
String modelName = matcher.group(1);
|
||||
Long modelId = new Long(matcher.group(2));
|
||||
Long modelId = Long.valueOf(matcher.group(2));
|
||||
this.logger.trace("Transforming model {} ID: {}", modelName, modelId);
|
||||
|
||||
this.transform(transformer, modelFile, modelName, modelId);
|
||||
|
@ -1,10 +1,39 @@
|
||||
/*
|
||||
* 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.maven.aps.modeling.crawler;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* This interface provides a common method for transforming various files in an
|
||||
* exported APS App.
|
||||
*
|
||||
* @author brian@inteligr8.com
|
||||
*/
|
||||
public interface ApsFileTransformer {
|
||||
|
||||
/**
|
||||
* This method transforms the specified file which should be referred to
|
||||
* with the specified name and ID.
|
||||
*
|
||||
* @param file A model file.
|
||||
* @param modelName The target model name.
|
||||
* @param modelId The target model ID.
|
||||
* @throws IOException An I/O related exception has occurred during transformation.
|
||||
*/
|
||||
void transformFile(File file, String modelName, Long modelId) throws IOException;
|
||||
|
||||
}
|
||||
|
@ -1,3 +1,17 @@
|
||||
/*
|
||||
* 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.maven.aps.modeling.goal;
|
||||
|
||||
import org.apache.maven.execution.MavenSession;
|
||||
@ -8,6 +22,14 @@ import com.inteligr8.alfresco.activiti.ApsClientJerseyConfiguration;
|
||||
import com.inteligr8.alfresco.activiti.ApsClientJerseyImpl;
|
||||
import com.inteligr8.alfresco.activiti.ApsPublicRestApiJerseyImpl;
|
||||
|
||||
/**
|
||||
* This class adds APS addressbility to extending goals.
|
||||
*
|
||||
* This is a common need for several goals in this library, as most of those
|
||||
* goals will need to call an APS service to perform their work.
|
||||
*
|
||||
* @author brian@inteligr8.com
|
||||
*/
|
||||
public abstract class ApsAddressibleGoal extends DisablableGoal {
|
||||
|
||||
@Parameter( defaultValue = "${session}", readonly = true )
|
||||
@ -36,6 +58,14 @@ public abstract class ApsAddressibleGoal extends DisablableGoal {
|
||||
|
||||
private ApsPublicRestApiJerseyImpl api;
|
||||
|
||||
/**
|
||||
* Retrieves an APS client configuration.
|
||||
*
|
||||
* The configuration is built based on the properties injected into this
|
||||
* class. It supports either `BASIC` or `OAuth` based authentication.
|
||||
*
|
||||
* @return An APS client configuration.
|
||||
*/
|
||||
public ApsClientJerseyConfiguration getApsClientConfiguration() {
|
||||
this.getLog().debug("Configuring APS to URL: " + this.activitiAppBaseUrl);
|
||||
ApsClientJerseyConfiguration config = new ApsClientJerseyConfiguration();
|
||||
@ -86,6 +116,9 @@ public abstract class ApsAddressibleGoal extends DisablableGoal {
|
||||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return An APS API instance.
|
||||
*/
|
||||
public synchronized ApsPublicRestApiJerseyImpl getApsApi() {
|
||||
if (this.api == null) {
|
||||
ApsClientJerseyConfiguration config = this.getApsClientConfiguration();
|
||||
|
@ -1,3 +1,17 @@
|
||||
/*
|
||||
* 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.maven.aps.modeling.goal;
|
||||
|
||||
import java.util.HashMap;
|
||||
@ -13,11 +27,28 @@ import com.inteligr8.alfresco.activiti.model.Datum;
|
||||
import com.inteligr8.alfresco.activiti.model.ResultListDataRepresentation;
|
||||
import com.inteligr8.alfresco.activiti.model.Tenant;
|
||||
|
||||
/**
|
||||
* This class adds the APS App name to APS addressibility to extending goals.
|
||||
*
|
||||
* Only use this class if your goal needs both the APS name and an APS service
|
||||
* client. You can use `ApsAppGoal` or `ApsAddressibleGoal` if you only need
|
||||
* one of those capabilities.
|
||||
*
|
||||
* @author brian@inteligr8.com
|
||||
*/
|
||||
public abstract class ApsAppAccessibleGoal extends ApsAddressibleGoal {
|
||||
|
||||
@Parameter( property = "aps-model.appName", required = true )
|
||||
protected String apsAppName;
|
||||
|
||||
/**
|
||||
* This method makes the appropriate service calls to find the first APS
|
||||
* tenant ID from the configured APS service.
|
||||
*
|
||||
* This method does not cache the result.
|
||||
*
|
||||
* @return An APS tenant ID; null only if there are no tenants.
|
||||
*/
|
||||
protected Long findTenantId() {
|
||||
List<Tenant> tenants = this.getApsApi().getAdminApi().getTenants();
|
||||
if (tenants == null || tenants.isEmpty())
|
||||
@ -25,6 +56,14 @@ public abstract class ApsAppAccessibleGoal extends ApsAddressibleGoal {
|
||||
return tenants.iterator().next().getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method makes the appropriate service calls to find all the APS
|
||||
* Apps, returning them as a map of names to IDs.
|
||||
*
|
||||
* This method does not cache the result.
|
||||
*
|
||||
* @return A map of APS App names to their respective IDs; may be empty; never null.
|
||||
*/
|
||||
protected Map<String, Long> findAppNameIds() {
|
||||
ApsPublicRestApiJerseyImpl api = this.getApsApi();
|
||||
|
||||
@ -42,10 +81,31 @@ public abstract class ApsAppAccessibleGoal extends ApsAddressibleGoal {
|
||||
return apps;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method makes the appropriate service calls to find the APS App by
|
||||
* the configured APS App name.
|
||||
*
|
||||
* This method does not cache the result.
|
||||
*
|
||||
* @param failOnNotFound true to fail if not found; false to return null.
|
||||
* @return An APS App ID; null if not found.
|
||||
* @throws MojoExecutionException The APS App could not be found.
|
||||
*/
|
||||
protected Long findAppId(boolean failOnNotFound) throws MojoExecutionException {
|
||||
return this.findAppIdByName(this.apsAppName, failOnNotFound);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method makes the appropriate service calls to find an APS App by
|
||||
* the specified APS App name.
|
||||
*
|
||||
* This method does not cache the result.
|
||||
*
|
||||
* @param apsName An APS App name.
|
||||
* @param failOnNotFound true to fail if not found; false to return null.
|
||||
* @return An APS App ID; null if not found.
|
||||
* @throws MojoExecutionException The APS App could not be found.
|
||||
*/
|
||||
protected Long findAppIdByName(String appName, boolean failOnNotFound) throws MojoExecutionException {
|
||||
Map<String, Long> apps = this.findAppNameIds();
|
||||
Long appId = apps.get(this.apsAppName);
|
||||
|
@ -1,7 +1,26 @@
|
||||
/*
|
||||
* 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.maven.aps.modeling.goal;
|
||||
|
||||
import org.apache.maven.plugins.annotations.Parameter;
|
||||
|
||||
/**
|
||||
* This class adds the APS App name to extending goals.
|
||||
*
|
||||
* @author brian@inteligr8.com
|
||||
*/
|
||||
public abstract class ApsAppGoal extends DisablableGoal {
|
||||
|
||||
@Parameter( property = "aps-model.appName", required = true )
|
||||
|
@ -1,3 +1,17 @@
|
||||
/*
|
||||
* 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.maven.aps.modeling.goal;
|
||||
|
||||
import org.apache.maven.plugin.MojoExecutionException;
|
||||
@ -7,6 +21,15 @@ import org.codehaus.plexus.component.annotations.Component;
|
||||
|
||||
import com.inteligr8.alfresco.activiti.model.AppVersion;
|
||||
|
||||
/**
|
||||
* A class that implements an APS service information goal.
|
||||
*
|
||||
* This goal will simply output the APS edition and version to the Maven output
|
||||
* at the `INFO` level. It is a great way to test your connection
|
||||
* configuration and network accessibility of the service.
|
||||
*
|
||||
* @author brian@inteligr8.com
|
||||
*/
|
||||
@Mojo( name = "aps-info", threadSafe = true )
|
||||
@Component( role = org.apache.maven.plugin.Mojo.class )
|
||||
public class ApsInfoGoal extends ApsAddressibleGoal {
|
||||
|
@ -1,3 +1,17 @@
|
||||
/*
|
||||
* 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.maven.aps.modeling.goal;
|
||||
|
||||
import java.util.Arrays;
|
||||
@ -24,6 +38,17 @@ import com.inteligr8.alfresco.activiti.model.SharePermission;
|
||||
import com.inteligr8.alfresco.activiti.model.Tenant;
|
||||
import com.inteligr8.maven.aps.modeling.util.Index;
|
||||
|
||||
/**
|
||||
* A class that implements a way to 'share' APS models.
|
||||
*
|
||||
* All APS models are automatically owned by the person that creates them. The
|
||||
* model is then not viewable or editable by anyone else, except for APS
|
||||
* administrators. This class provides a way to automatically 'share' the
|
||||
* synchronized models to groups or individual users. The 'share' may have
|
||||
* readonly or editing capabilities, as configured.
|
||||
*
|
||||
* @author brian@inteligr8.com
|
||||
*/
|
||||
@Mojo( name = "share-models", threadSafe = true )
|
||||
@Component( role = org.apache.maven.plugin.Mojo.class )
|
||||
public class ApsShareGoal extends ApsAddressibleGoal {
|
||||
|
@ -1,3 +1,17 @@
|
||||
/*
|
||||
* 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.maven.aps.modeling.goal;
|
||||
|
||||
import org.apache.maven.plugin.AbstractMojo;
|
||||
@ -5,6 +19,10 @@ import org.apache.maven.plugin.MojoExecutionException;
|
||||
import org.apache.maven.plugin.MojoFailureException;
|
||||
import org.apache.maven.plugins.annotations.Parameter;
|
||||
|
||||
/**
|
||||
* This class adds enable/disable capability to any goal. It uses the standard
|
||||
* 'skip' terminology.
|
||||
*/
|
||||
public abstract class DisablableGoal extends AbstractMojo {
|
||||
|
||||
@Parameter( property = "aps-model.skip", required = true, defaultValue = "false" )
|
||||
@ -24,6 +42,14 @@ public abstract class DisablableGoal extends AbstractMojo {
|
||||
this.executeEnabled();
|
||||
}
|
||||
|
||||
/**
|
||||
* Identical to the `AbstractMojo.execute()` method, but it is only called
|
||||
* when this is enabled.
|
||||
*
|
||||
* @throws MojoExecutionException The goal failed to execute.
|
||||
* @throws MojoFailureException The goal failed whiling executing.
|
||||
* @see org.apache.maven.plugin.AbstractMojo.execute()
|
||||
*/
|
||||
public abstract void executeEnabled() throws MojoExecutionException, MojoFailureException;
|
||||
|
||||
}
|
||||
|
@ -1,3 +1,17 @@
|
||||
/*
|
||||
* 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.maven.aps.modeling.goal;
|
||||
|
||||
import java.io.File;
|
||||
@ -12,6 +26,15 @@ import org.codehaus.plexus.component.annotations.Component;
|
||||
|
||||
import com.inteligr8.alfresco.activiti.ApsPublicRestApiJerseyImpl;
|
||||
|
||||
/**
|
||||
* A class that implements an APS service download goal.
|
||||
*
|
||||
* This goal will simply download the APS App with the specified name from the
|
||||
* specified APS service. The downloaded APS App will remain packed (zipped).
|
||||
* If a file exists with a conflicting name, it will be overwritten.
|
||||
*
|
||||
* @author brian@inteligr8.com
|
||||
*/
|
||||
@Mojo( name = "download-app", threadSafe = true )
|
||||
@Component( role = org.apache.maven.plugin.Mojo.class )
|
||||
public class DownloadAppGoal extends ApsAppAccessibleGoal {
|
||||
|
@ -1,3 +1,17 @@
|
||||
/*
|
||||
* 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.maven.aps.modeling.goal;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
@ -18,6 +32,15 @@ import org.apache.maven.plugins.annotations.Mojo;
|
||||
import org.apache.maven.plugins.annotations.Parameter;
|
||||
import org.codehaus.plexus.component.annotations.Component;
|
||||
|
||||
/**
|
||||
* A class that implements an APS App packaging goal.
|
||||
*
|
||||
* This goal will simply pack (zip) a folder containing an APS App file
|
||||
* structure. If a file exists with a conflicting name, it will be
|
||||
* overwritten.
|
||||
*
|
||||
* @author brian@inteligr8.com
|
||||
*/
|
||||
@Mojo( name = "pack-app", threadSafe = true )
|
||||
@Component( role = org.apache.maven.plugin.Mojo.class )
|
||||
public class PackAppGoal extends ApsAppGoal {
|
||||
|
@ -1,3 +1,17 @@
|
||||
/*
|
||||
* 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.maven.aps.modeling.goal;
|
||||
|
||||
import java.io.IOException;
|
||||
@ -11,6 +25,14 @@ import org.codehaus.plexus.component.annotations.Component;
|
||||
import com.inteligr8.alfresco.activiti.ApsPublicRestApiJerseyImpl;
|
||||
import com.inteligr8.alfresco.activiti.model.AppDefinitionPublishRepresentation;
|
||||
|
||||
/**
|
||||
* A class that implements an APS Service publish goal.
|
||||
*
|
||||
* This goal will simply attempt to publish an existing APS App using the APS
|
||||
* Service. It is typically used in conjuection with the `upload-app` goal.
|
||||
*
|
||||
* @author brian@inteligr8.com
|
||||
*/
|
||||
@Mojo( name = "publish-app", threadSafe = true )
|
||||
@Component( role = org.apache.maven.plugin.Mojo.class )
|
||||
public class PublishAppGoal extends ApsAppAccessibleGoal {
|
||||
|
@ -1,3 +1,17 @@
|
||||
/*
|
||||
* 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.maven.aps.modeling.goal;
|
||||
|
||||
import java.io.File;
|
||||
@ -13,6 +27,20 @@ import org.codehaus.plexus.component.annotations.Component;
|
||||
import com.inteligr8.maven.aps.modeling.crawler.ApsAppCrawler;
|
||||
import com.inteligr8.maven.aps.modeling.translator.ApsAppTranslator;
|
||||
|
||||
/**
|
||||
* A class that implements an APS App translation goal.
|
||||
*
|
||||
* This goal will translate all the JSON and XML files in an APS App to match
|
||||
* the environment referenced by the specified APS App. This relies on all APS
|
||||
* model elements (apps, processes, and forms) to have unique names. The names
|
||||
* of those mdoel elements are used to remap IDs between environments.
|
||||
*
|
||||
* APS does not enforce a unique name constraint. But it is good practice to
|
||||
* avoid using the same name anyhow. This plugin will just make you do it. It
|
||||
* will error if a duplicate is detected.
|
||||
*
|
||||
* @author brian@inteligr8.com
|
||||
*/
|
||||
@Mojo( name = "translate-app", threadSafe = true )
|
||||
@Component( role = org.apache.maven.plugin.Mojo.class )
|
||||
public class TranslateAppGoal extends ApsAppAccessibleGoal {
|
||||
|
@ -1,3 +1,17 @@
|
||||
/*
|
||||
* 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.maven.aps.modeling.goal;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
@ -29,6 +43,15 @@ import com.inteligr8.maven.aps.modeling.crawler.ApsAppCrawler;
|
||||
import com.inteligr8.maven.aps.modeling.normalizer.ApsAppNormalizer;
|
||||
import com.inteligr8.maven.aps.modeling.util.ModelUtil;
|
||||
|
||||
/**
|
||||
* A class that implements an APS App unpackaging goal.
|
||||
*
|
||||
* This goal will simply unpack (unzip) an APS App export into a folder. If a
|
||||
* folder of the APS App name already exists, it will be cleared before the
|
||||
* export is unpacked into it.
|
||||
*
|
||||
* @author brian@inteligr8.com
|
||||
*/
|
||||
@Mojo( name = "unpack-app", threadSafe = true )
|
||||
@Component( role = org.apache.maven.plugin.Mojo.class )
|
||||
public class UnpackAppGoal extends ApsAppGoal {
|
||||
|
@ -1,3 +1,17 @@
|
||||
/*
|
||||
* 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.maven.aps.modeling.goal;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
@ -16,6 +30,16 @@ import com.inteligr8.alfresco.activiti.ApsPublicRestApiJerseyImpl;
|
||||
import com.inteligr8.alfresco.activiti.model.AppDefinitionUpdateResultRepresentation;
|
||||
import com.inteligr8.alfresco.activiti.model.FileMultipartJersey;
|
||||
|
||||
/**
|
||||
* A class that implements an APS service upload goal.
|
||||
*
|
||||
* This goal will simply upload an APS App package with the specified name to
|
||||
* the specified APS service. Any IDs specified in the uploaded package must
|
||||
* match existing IDs for them to properly version. That is the main purpose
|
||||
* of this plugin and can be achieved using the 'translate-app' goal.
|
||||
*
|
||||
* @author brian@inteligr8.com
|
||||
*/
|
||||
@Mojo( name = "upload-app", threadSafe = true )
|
||||
@Component( role = org.apache.maven.plugin.Mojo.class )
|
||||
public class UploadAppGoal extends ApsAppAccessibleGoal {
|
||||
|
@ -1,3 +1,17 @@
|
||||
/*
|
||||
* 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.maven.aps.modeling.normalizer;
|
||||
|
||||
import java.io.File;
|
||||
@ -13,12 +27,30 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import com.inteligr8.maven.aps.modeling.util.ApsModelArrayNodeSorter;
|
||||
import com.inteligr8.maven.aps.modeling.util.ModelUtil;
|
||||
|
||||
/**
|
||||
* This class implements an APS App JSON configuration file normalizer.
|
||||
*
|
||||
* This will remove the 'lastUpdated' date of each defined process model. It
|
||||
* will also order the process 'models' by their respective 'name' values.
|
||||
*
|
||||
* @author brian@inteligr8.com
|
||||
*/
|
||||
public class ApsAppJsonNormalizer implements ApsFileNormalizer {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(ApsAppJsonNormalizer.class);
|
||||
|
||||
private final boolean enableSorting;
|
||||
|
||||
/**
|
||||
* This constructor initializes the default normalizer with or without
|
||||
* sorting.
|
||||
*
|
||||
* The sorting feature is available for a better "diff" experience. If
|
||||
* you intend to commit the APS App configurations to Git, you will want to
|
||||
* enable sorting.
|
||||
*
|
||||
* @param enableSorting true to re-order JSON objects; false to keep as-is.
|
||||
*/
|
||||
public ApsAppJsonNormalizer(boolean enableSorting) {
|
||||
this.enableSorting = enableSorting;
|
||||
}
|
||||
|
@ -1,12 +1,54 @@
|
||||
/*
|
||||
* 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.maven.aps.modeling.normalizer;
|
||||
|
||||
import com.inteligr8.maven.aps.modeling.crawler.ApsAppCrawlable;
|
||||
import com.inteligr8.maven.aps.modeling.crawler.ApsFileTransformer;
|
||||
|
||||
/**
|
||||
* This class defines an APS App package normalizer.
|
||||
*
|
||||
* An APS App package is a ZIP file that contains multiple files in a
|
||||
* predictable folder hierachy with predictable file names. It is effectively
|
||||
* an APS App interchange format specification.
|
||||
*
|
||||
* A package must have at least a single configuration file at the root of the
|
||||
* ZIP package in the JSON format. It must be named the APS App name. That
|
||||
* file will then reference all the model elements contained in the ZIP. Any
|
||||
* model elements not referenced will simply be ignored by APS and by this
|
||||
* plugin.
|
||||
*
|
||||
* This class has methods that provide normalizer for all the various model
|
||||
* elements in an APS App package.
|
||||
*
|
||||
* @author brian@inteligr8.com
|
||||
*/
|
||||
public class ApsAppNormalizer implements ApsAppCrawlable {
|
||||
|
||||
private final boolean enableSorting;
|
||||
|
||||
/**
|
||||
* This constructor initializes the default normalizer with or without
|
||||
* sorting.
|
||||
*
|
||||
* The sorting feature is available for a better "diff" experience. If
|
||||
* you intend to commit the APS App configurations to Git, you will want to
|
||||
* enable sorting.
|
||||
*
|
||||
* @param enableSorting true to re-order JSON objects; false to keep as-is.
|
||||
*/
|
||||
public ApsAppNormalizer(boolean enableSorting) {
|
||||
this.enableSorting = enableSorting;
|
||||
}
|
||||
|
@ -1,7 +1,33 @@
|
||||
/*
|
||||
* 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.maven.aps.modeling.normalizer;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import com.inteligr8.maven.aps.modeling.crawler.ApsFileTransformer;
|
||||
|
||||
/**
|
||||
* This interface defines an APS file normalizer.
|
||||
*
|
||||
* Normalization is the transformation of something from one state to a target
|
||||
* (normalized) state. In this context, a configuration is being normalized to
|
||||
* be diff-friendly. That principally means the removal of dates. In theory,
|
||||
* two normalized files will always match unless something of real substance
|
||||
* has changed.
|
||||
*/
|
||||
public interface ApsFileNormalizer extends ApsFileTransformer {
|
||||
|
||||
}
|
||||
|
@ -1,3 +1,17 @@
|
||||
/*
|
||||
* 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.maven.aps.modeling.normalizer;
|
||||
|
||||
import java.io.File;
|
||||
@ -6,6 +20,13 @@ import java.io.IOException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* This class implements an APS Form JSON configuration file normalizer.
|
||||
*
|
||||
* This does nothing but log at this time.
|
||||
*
|
||||
* @author brian@inteligr8.com
|
||||
*/
|
||||
public class ApsFormJsonNormalizer implements ApsFileNormalizer {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(ApsFormJsonNormalizer.class);
|
||||
|
@ -1,3 +1,17 @@
|
||||
/*
|
||||
* 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.maven.aps.modeling.normalizer;
|
||||
|
||||
import java.io.File;
|
||||
@ -14,6 +28,14 @@ import org.xml.sax.SAXException;
|
||||
|
||||
import com.inteligr8.maven.aps.modeling.util.ModelUtil;
|
||||
|
||||
/**
|
||||
* This class implements an APS Process BPMN/XML configuration file normalizer.
|
||||
*
|
||||
* This will remove the 'exportDateTime' and 'modelLastUpdated' dates and
|
||||
* 'modelVersion' of the process model.
|
||||
*
|
||||
* @author brian@inteligr8.com
|
||||
*/
|
||||
public class ApsProcessBpmnNormalizer implements ApsFileNormalizer {
|
||||
|
||||
private static final String NAMESPACE_ACTIVITI_MODELER = "http://activiti.com/modeler";
|
||||
|
@ -1,3 +1,17 @@
|
||||
/*
|
||||
* 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.maven.aps.modeling.normalizer;
|
||||
|
||||
import java.io.File;
|
||||
@ -12,12 +26,30 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import com.inteligr8.maven.aps.modeling.util.ApsModelArrayNodeSorter;
|
||||
import com.inteligr8.maven.aps.modeling.util.ModelUtil;
|
||||
|
||||
/**
|
||||
* This class implements an APS Process JSON configuration file normalizer.
|
||||
*
|
||||
* This will do nothing unless sorting is enabled. With sorting, it will order
|
||||
* the 'childShapes' by their respective 'resourceId' values.
|
||||
*
|
||||
* @author brian@inteligr8.com
|
||||
*/
|
||||
public class ApsProcessJsonNormalizer implements ApsFileNormalizer {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(ApsProcessJsonNormalizer.class);
|
||||
|
||||
private final boolean enableSorting;
|
||||
|
||||
/**
|
||||
* This constructor initializes the default normalizer with or without
|
||||
* sorting.
|
||||
*
|
||||
* The sorting feature is available for a better "diff" experience. If
|
||||
* you intend to commit the APS App configurations to Git, you will want to
|
||||
* enable sorting.
|
||||
*
|
||||
* @param enableSorting true to re-order JSON objects; false to keep as-is.
|
||||
*/
|
||||
public ApsProcessJsonNormalizer(boolean enableSorting) {
|
||||
this.enableSorting = enableSorting;
|
||||
}
|
||||
@ -33,8 +65,10 @@ public class ApsProcessJsonNormalizer implements ApsFileNormalizer {
|
||||
|
||||
ObjectNode jsonDescriptor = ModelUtil.getInstance().readJson(file, ObjectNode.class);
|
||||
ArrayNode jsonChildShapes = this.getChildShapes(jsonDescriptor);
|
||||
this.logger.trace("Found Process shapes: {}: {}", modelName, jsonChildShapes.size());
|
||||
|
||||
changed = ApsModelArrayNodeSorter.getInstance().sort(jsonChildShapes, "resourceId") || changed;
|
||||
changed = ArrayNodeObjectSorter.getInstance().sort(jsonChildShapes, "resourceId") || changed;
|
||||
this.logger.trace("Sorted Process shapes: {}: {}", modelName, changed);
|
||||
|
||||
if (changed)
|
||||
ModelUtil.getInstance().writeJson(jsonDescriptor, file, this.enableSorting);
|
||||
|
@ -1,3 +1,17 @@
|
||||
/*
|
||||
* 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.maven.aps.modeling.translator;
|
||||
|
||||
import java.io.File;
|
||||
@ -15,6 +29,19 @@ import com.inteligr8.alfresco.activiti.model.GroupLight;
|
||||
import com.inteligr8.maven.aps.modeling.util.Index;
|
||||
import com.inteligr8.maven.aps.modeling.util.ModelUtil;
|
||||
|
||||
/**
|
||||
* This class implements an APS App JSON configuration file translator.
|
||||
*
|
||||
* This will translate the IDs of all the APS App, Processes, and Organizations
|
||||
* referenced in the APS App descriptor.
|
||||
*
|
||||
* Caution: in lieu of implementing APS User translation, APS User identity
|
||||
* references are simply removed. Using APS Users in your APS models is bad
|
||||
* practice. Use APS Organizations, even if that user is the only member of
|
||||
* the group.
|
||||
*
|
||||
* @author brian@inteligr8.com
|
||||
*/
|
||||
public class ApsAppJsonTranslator extends ApsOrganizationHandler implements ApsFileTranslator {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(ApsAppJsonTranslator.class);
|
||||
@ -22,35 +49,45 @@ public class ApsAppJsonTranslator extends ApsOrganizationHandler implements ApsF
|
||||
private final Index<Long, String> apsProcessIndex;
|
||||
private final Index<Long, String> fileProcessIndex;
|
||||
|
||||
/**
|
||||
* This constructor initializes the default translator.
|
||||
*
|
||||
* @param api An APS API reference.
|
||||
* @param apsProcessIndex A map of process IDs to process names as defined in the APS Service.
|
||||
* @param apsOrgIndex A map of organizations (groups) to organization meta-data as defined in the APS Service.
|
||||
* @param fileProcessIndex A map of process IDs to process names as used in the local process files.
|
||||
*/
|
||||
public ApsAppJsonTranslator(
|
||||
ApsPublicRestApi api,
|
||||
Map<String, GroupLight> apsOrgIndex,
|
||||
Index<Long, String> apsProcessIndex,
|
||||
Map<String, GroupLight> apsOrgIndex,
|
||||
Index<Long, String> fileProcessIndex) {
|
||||
super(api, apsOrgIndex);
|
||||
this.apsOrgIndex = apsOrgIndex;
|
||||
this.apsProcessIndex = apsProcessIndex;
|
||||
this.apsOrgIndex = apsOrgIndex;
|
||||
this.fileProcessIndex = fileProcessIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translateFile(File file, String modelName, Long modelId) throws IOException {
|
||||
public void translateFile(File file, String appName, Long appId) throws IOException {
|
||||
this.logger.debug("Translating JSON file: {}", file);
|
||||
|
||||
boolean changed = false;
|
||||
JsonNode descriptor = ModelUtil.getInstance().readJson(file);
|
||||
|
||||
JsonNode jsonDescriptor = ModelUtil.getInstance().readJson(file);
|
||||
|
||||
changed = this.translateModels(descriptor) || changed;
|
||||
changed = this.translateIdentities(descriptor) || changed;
|
||||
changed = this.translateModels(jsonDescriptor, appName) || changed;
|
||||
changed = this.translateIdentities(jsonDescriptor, appName) || changed;
|
||||
|
||||
if (changed)
|
||||
ModelUtil.getInstance().writeJson(descriptor, file, false);
|
||||
ModelUtil.getInstance().writeJson(jsonDescriptor, file, false);
|
||||
}
|
||||
|
||||
private boolean translateModels(JsonNode descriptor) {
|
||||
private boolean translateModels(JsonNode jsonDescriptor, String appName) {
|
||||
this.logger.trace("Translating processes in App: {}", appName);
|
||||
boolean changed = false;
|
||||
|
||||
for (JsonNode _jsonModel : descriptor.get("definition").get("models")) {
|
||||
for (JsonNode _jsonModel : jsonDescriptor.get("definition").get("models")) {
|
||||
ObjectNode jsonModel = (ObjectNode)_jsonModel;
|
||||
|
||||
String fileProcessName = jsonModel.get("name").asText();
|
||||
@ -91,10 +128,11 @@ public class ApsAppJsonTranslator extends ApsOrganizationHandler implements ApsF
|
||||
return changed;
|
||||
}
|
||||
|
||||
private boolean translateIdentities(JsonNode descriptor) {
|
||||
private boolean translateIdentities(JsonNode jsonDescriptor, String appName) {
|
||||
this.logger.trace("Translating identities in App: {}", appName);
|
||||
boolean changed = false;
|
||||
|
||||
Iterator<JsonNode> i = descriptor.get("definition").get("publishIdentityInfo").iterator();
|
||||
Iterator<JsonNode> i = jsonDescriptor.get("definition").get("publishIdentityInfo").iterator();
|
||||
while (i.hasNext()) {
|
||||
JsonNode jsonIdentityInfo = i.next();
|
||||
|
||||
|
@ -1,3 +1,17 @@
|
||||
/*
|
||||
* 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.maven.aps.modeling.translator;
|
||||
|
||||
import java.io.File;
|
||||
@ -13,7 +27,6 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.inteligr8.alfresco.activiti.ApsPublicRestApi;
|
||||
import com.inteligr8.alfresco.activiti.ApsPublicRestApiJerseyImpl;
|
||||
import com.inteligr8.alfresco.activiti.api.ModelsApi.ModelType;
|
||||
import com.inteligr8.alfresco.activiti.model.Datum;
|
||||
import com.inteligr8.alfresco.activiti.model.GroupLight;
|
||||
@ -23,6 +36,24 @@ import com.inteligr8.maven.aps.modeling.crawler.ApsAppCrawlable;
|
||||
import com.inteligr8.maven.aps.modeling.crawler.ApsFileTransformer;
|
||||
import com.inteligr8.maven.aps.modeling.util.Index;
|
||||
|
||||
/**
|
||||
* This class defines an APS App package translator.
|
||||
*
|
||||
* An APS App package is a ZIP file that contains multiple files in a
|
||||
* predictable folder hierachy with predictable file names. It is effectively
|
||||
* an APS App interchange format specification.
|
||||
*
|
||||
* A package must have at least a single configuration file at the root of the
|
||||
* ZIP package in the JSON format. It must be named the APS App name. That
|
||||
* file will then reference all the model elements contained in the ZIP. Any
|
||||
* model elements not referenced will simply be ignored by APS and by this
|
||||
* plugin.
|
||||
*
|
||||
* This class has methods that provide translator for all the various model
|
||||
* elements in an APS App package.
|
||||
*
|
||||
* @author brian@inteligr8.com
|
||||
*/
|
||||
public class ApsAppTranslator implements ApsAppCrawlable {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(ApsAppTranslator.class);
|
||||
@ -38,11 +69,27 @@ public class ApsAppTranslator implements ApsAppCrawlable {
|
||||
private Index<Long, String> fileProcessIndex;
|
||||
private Index<Long, String> fileSubprocessIndex;
|
||||
|
||||
public ApsAppTranslator(File apsAppDirectory, ApsPublicRestApiJerseyImpl api) {
|
||||
/**
|
||||
* This constructor initializes the default translator.
|
||||
*
|
||||
* The specified directory and a reference to the APS Service are both
|
||||
* required. This way the configuration file can be cross-referenced with
|
||||
* the APS App IDs on the target APS instance.
|
||||
*
|
||||
* @param apsAppDirectory The directory of the unpacked APS package.
|
||||
* @param api An APS API reference.
|
||||
*/
|
||||
public ApsAppTranslator(File apsAppDirectory, ApsPublicRestApi api) {
|
||||
this.api = api;
|
||||
this.appDirectory = apsAppDirectory;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method initializes the data required from the APS Service for the
|
||||
* function of this class.
|
||||
*
|
||||
* @throws IOException A network I/O related issue occurred.
|
||||
*/
|
||||
public synchronized void buildIndexes() throws IOException {
|
||||
if (this.indexesBuilt)
|
||||
return;
|
||||
@ -96,8 +143,8 @@ public class ApsAppTranslator implements ApsAppCrawlable {
|
||||
|
||||
return new ApsAppJsonTranslator(
|
||||
this.api,
|
||||
this.apsOrgIndex,
|
||||
this.apsProcessIndex,
|
||||
this.apsOrgIndex,
|
||||
this.fileProcessIndex);
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,17 @@
|
||||
/*
|
||||
* 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.maven.aps.modeling.translator;
|
||||
|
||||
import java.io.File;
|
||||
@ -5,6 +19,14 @@ import java.io.IOException;
|
||||
|
||||
import com.inteligr8.maven.aps.modeling.crawler.ApsFileTransformer;
|
||||
|
||||
/**
|
||||
* This interface defines an APS file translator.
|
||||
*
|
||||
* Translation is the transformation of something from one state to a target
|
||||
* state. In this context, a configuration is being translated to be import
|
||||
* friendly for the target APS Service. That principally means the update
|
||||
* of APS model IDs.
|
||||
*/
|
||||
public interface ApsFileTranslator extends ApsFileTransformer {
|
||||
|
||||
@Override
|
||||
@ -12,6 +34,15 @@ public interface ApsFileTranslator extends ApsFileTransformer {
|
||||
this.translateFile(file, modelName, modelId);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method translates the specified file which should be referred to
|
||||
* with the specified name and ID.
|
||||
*
|
||||
* @param file A model file.
|
||||
* @param modelName The target model name.
|
||||
* @param modelId The target model ID.
|
||||
* @throws IOException An I/O related exception has occurred during translation.
|
||||
*/
|
||||
void translateFile(File file, String modelName, Long modelId) throws IOException;
|
||||
|
||||
}
|
||||
|
@ -1,3 +1,17 @@
|
||||
/*
|
||||
* 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.maven.aps.modeling.translator;
|
||||
|
||||
import java.io.File;
|
||||
@ -11,11 +25,23 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import com.inteligr8.maven.aps.modeling.util.Index;
|
||||
import com.inteligr8.maven.aps.modeling.util.ModelUtil;
|
||||
|
||||
/**
|
||||
* This class implements an APS Form JSON configuration file translator.
|
||||
*
|
||||
* This will translate the form ID embedded into APS Form descriptor.
|
||||
*
|
||||
* @author brian@inteligr8.com
|
||||
*/
|
||||
public class ApsFormJsonTranslator implements ApsFileTranslator {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(ApsFormJsonTranslator.class);
|
||||
private final Index<Long, String> apsIndex;
|
||||
|
||||
/**
|
||||
* This constructor initializes the default translator.
|
||||
*
|
||||
* @param apsFormIndex A map of form IDs to form names as defined in the APS Service.
|
||||
*/
|
||||
public ApsFormJsonTranslator(Index<Long, String> apsFormIndex) {
|
||||
this.apsIndex = apsFormIndex;
|
||||
}
|
||||
|
@ -1,3 +1,17 @@
|
||||
/*
|
||||
* 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.maven.aps.modeling.translator;
|
||||
|
||||
import java.util.Map;
|
||||
@ -9,12 +23,21 @@ import com.inteligr8.alfresco.activiti.ApsPublicRestApi;
|
||||
import com.inteligr8.alfresco.activiti.model.Group;
|
||||
import com.inteligr8.alfresco.activiti.model.GroupLight;
|
||||
|
||||
/**
|
||||
* This class provides APS Organization support.
|
||||
*
|
||||
* @author brian@inteligr8.com.
|
||||
*/
|
||||
public class ApsOrganizationHandler {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(ApsOrganizationHandler.class);
|
||||
private final ApsPublicRestApi api;
|
||||
private final Map<String, GroupLight> apsOrgIndex;
|
||||
|
||||
/**
|
||||
* @param api An APS API reference.
|
||||
* @param apsOrgIndex A map of organization IDs to organization meta-data defined in the APS service.
|
||||
*/
|
||||
public ApsOrganizationHandler(
|
||||
ApsPublicRestApi api,
|
||||
Map<String, GroupLight> apsOrgIndex) {
|
||||
|
@ -1,3 +1,17 @@
|
||||
/*
|
||||
* 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.maven.aps.modeling.translator;
|
||||
|
||||
import java.io.File;
|
||||
@ -27,6 +41,19 @@ import com.inteligr8.alfresco.activiti.model.GroupLight;
|
||||
import com.inteligr8.maven.aps.modeling.util.Index;
|
||||
import com.inteligr8.maven.aps.modeling.util.ModelUtil;
|
||||
|
||||
/**
|
||||
* This class implements an APS Process BPMN/XML configuration file translator.
|
||||
*
|
||||
* This will translate the IDs of all the APS Process, Organizations, and
|
||||
* Forms referenced in the APS Process BPMN.
|
||||
*
|
||||
* Caution: in lieu of implementing APS User translation, APS User identity
|
||||
* references are simply removed. Using APS Users in your APS models is bad
|
||||
* practice. Use APS Organizations, even if that user is the only member of
|
||||
* the group.
|
||||
*
|
||||
* @author brian@inteligr8.com
|
||||
*/
|
||||
public class ApsProcessBpmnTranslator extends ApsOrganizationHandler implements ApsFileTranslator {
|
||||
|
||||
private static final String NAMESPACE_ACTIVITI = "http://activiti.org/bpmn";
|
||||
@ -38,6 +65,15 @@ public class ApsProcessBpmnTranslator extends ApsOrganizationHandler implements
|
||||
private final Index<Long, String> apsFormIndex;
|
||||
private final Index<Long, String> fileFormIndex;
|
||||
|
||||
/**
|
||||
* This constructor initializes the default translator.
|
||||
*
|
||||
* @param api An APS API reference.
|
||||
* @param apsProcessIndex A map of process IDs to process names as defined in the APS Service.
|
||||
* @param apsOrgIndex A map of organizations (groups) to organization meta-data as defined in the APS Service.
|
||||
* @param apsFormIndex A map of form IDs to form names as defined in the APS Service.
|
||||
* @param fileFormIndex A map of form IDS to form names as used in the local form files.
|
||||
*/
|
||||
public ApsProcessBpmnTranslator(
|
||||
ApsPublicRestApi api,
|
||||
Index<Long, String> apsProcessIndex,
|
||||
|
@ -1,3 +1,17 @@
|
||||
/*
|
||||
* 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.maven.aps.modeling.translator;
|
||||
|
||||
import java.io.File;
|
||||
@ -15,6 +29,19 @@ import com.inteligr8.alfresco.activiti.model.GroupLight;
|
||||
import com.inteligr8.maven.aps.modeling.util.Index;
|
||||
import com.inteligr8.maven.aps.modeling.util.ModelUtil;
|
||||
|
||||
/**
|
||||
* This class implements an APS Process JSON configuration file translator.
|
||||
*
|
||||
* This will translate the IDs of all the APS Process, Organizations, and
|
||||
* Forms referenced in the APS Process descriptor.
|
||||
*
|
||||
* Caution: in lieu of implementing APS User translation, APS User identity
|
||||
* references are simply removed. Using APS Users in your APS models is bad
|
||||
* practice. Use APS Organizations, even if that user is the only member of
|
||||
* the group.
|
||||
*
|
||||
* @author brian@inteligr8.com
|
||||
*/
|
||||
public class ApsProcessJsonTranslator extends ApsOrganizationHandler implements ApsFileTranslator {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(ApsProcessJsonTranslator.class);
|
||||
@ -22,6 +49,14 @@ public class ApsProcessJsonTranslator extends ApsOrganizationHandler implements
|
||||
private final Map<String, GroupLight> apsOrgIndex;
|
||||
private final Index<Long, String> apsFormIndex;
|
||||
|
||||
/**
|
||||
* This constructor initializes the default translator.
|
||||
*
|
||||
* @param api An APS API reference.
|
||||
* @param apsProcessIndex A map of process IDs to process names as defined in the APS Service.
|
||||
* @param apsOrgIndex A map of organizations (groups) to organization meta-data as defined in the APS Service.
|
||||
* @param apsFormIndex A map of form IDs to form names as defined in the APS Service.
|
||||
*/
|
||||
public ApsProcessJsonTranslator(
|
||||
ApsPublicRestApi api,
|
||||
Index<Long, String> apsProcessIndex,
|
||||
@ -42,21 +77,22 @@ public class ApsProcessJsonTranslator extends ApsOrganizationHandler implements
|
||||
|
||||
ObjectNode jsonDescriptor = ModelUtil.getInstance().readJson(file, ObjectNode.class);
|
||||
|
||||
changed = this.translateResourceId(jsonDescriptor, apsProcessId) || changed;
|
||||
changed = this.translateOrganizations(jsonDescriptor) || changed;
|
||||
changed = this.translateForms(jsonDescriptor) || changed;
|
||||
changed = this.translateSubprocesses(jsonDescriptor) || changed;
|
||||
changed = this.translateResourceId(jsonDescriptor, processName, apsProcessId) || changed;
|
||||
changed = this.translateOrganizations(jsonDescriptor, processName) || changed;
|
||||
changed = this.translateForms(jsonDescriptor, processName) || changed;
|
||||
changed = this.translateSubprocesses(jsonDescriptor, processName) || changed;
|
||||
|
||||
if (changed)
|
||||
ModelUtil.getInstance().writeJson(jsonDescriptor, file, false);
|
||||
}
|
||||
|
||||
private boolean translateResourceId(ObjectNode jsonDescriptor, Long apsProcessId) {
|
||||
private boolean translateResourceId(ObjectNode jsonDescriptor, String processName, Long apsProcessId) {
|
||||
if (apsProcessId == null) {
|
||||
this.logger.trace("The process is not in APS; treating as new");
|
||||
return false;
|
||||
}
|
||||
|
||||
this.logger.trace("Translating resource ID in process: {}", processName);
|
||||
ObjectNode resourceIdParentJson = jsonDescriptor;
|
||||
|
||||
JsonNode jsonResourceId = jsonDescriptor.get("resourceId");
|
||||
@ -83,7 +119,8 @@ public class ApsProcessJsonTranslator extends ApsOrganizationHandler implements
|
||||
|
||||
|
||||
|
||||
private boolean translateOrganizations(ObjectNode jsonDescriptor) {
|
||||
private boolean translateOrganizations(ObjectNode jsonDescriptor, String processName) {
|
||||
this.logger.trace("Translating organizations in process: {}", processName);
|
||||
boolean changed = false;
|
||||
|
||||
for (JsonNode jsonChildShape : this.getChildShapes(jsonDescriptor)) {
|
||||
@ -134,7 +171,8 @@ public class ApsProcessJsonTranslator extends ApsOrganizationHandler implements
|
||||
|
||||
|
||||
|
||||
private boolean translateForms(ObjectNode jsonDescriptor) {
|
||||
private boolean translateForms(ObjectNode jsonDescriptor, String processName) {
|
||||
this.logger.trace("Translating forms in process: {}", processName);
|
||||
boolean changed = false;
|
||||
|
||||
for (JsonNode jsonChildShape : this.getChildShapes(jsonDescriptor)) {
|
||||
@ -168,7 +206,8 @@ public class ApsProcessJsonTranslator extends ApsOrganizationHandler implements
|
||||
|
||||
|
||||
|
||||
private boolean translateSubprocesses(ObjectNode jsonDescriptor) {
|
||||
private boolean translateSubprocesses(ObjectNode jsonDescriptor, String processName) {
|
||||
this.logger.trace("Translating subprocesses in process: {}", processName);
|
||||
boolean changed = false;
|
||||
|
||||
for (JsonNode jsonChildShape : this.getChildShapes(jsonDescriptor)) {
|
||||
|
@ -1,3 +1,17 @@
|
||||
/*
|
||||
* 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.maven.aps.modeling.util;
|
||||
|
||||
import java.util.HashMap;
|
||||
@ -9,55 +23,114 @@ import java.util.Set;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
/**
|
||||
* A class that implements bi-directional map for forward and reverse indexing
|
||||
* and lookups.
|
||||
*
|
||||
* The index is considered to be many-to-1. So the forward index appears as
|
||||
* 1-to-1 (one key to one value) and the reverse index appears as 1-to-many
|
||||
* (one value to many keys).
|
||||
*
|
||||
* If the index should be considered to be 1-to-1, then set
|
||||
* `allowDuplicateValues` to `false`.
|
||||
*
|
||||
* @author brian@inteligr8.com
|
||||
*/
|
||||
public class Index<K, V> {
|
||||
|
||||
private final Map<K, V> forwardMap;
|
||||
private final Map<V, Set<K>> reverseMap;
|
||||
private final boolean allowDuplicateValues;
|
||||
|
||||
/**
|
||||
* This constructor defines a new index with some meta-data.
|
||||
*
|
||||
* The capacity is not strictly enforced. It should be accurate for
|
||||
* performance reasons.
|
||||
*
|
||||
* @param initialCapacity A capacity, as you would specify in an ArrayList or HashMap.
|
||||
* @param allowDuplicateValues true to allow multiple keys to have the same value; false to throw an IllegalArgumentException.
|
||||
*/
|
||||
public Index(int initialCapacity, boolean allowDuplicateValues) {
|
||||
this.forwardMap = new HashMap<K, V>(initialCapacity);
|
||||
this.reverseMap = new HashMap<V, Set<K>>(initialCapacity);
|
||||
this.allowDuplicateValues = allowDuplicateValues;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key An index key.
|
||||
* @return true if it exists; false otherwise.
|
||||
*/
|
||||
public boolean containsKey(K key) {
|
||||
return this.forwardMap.containsKey(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param value An indexed value.
|
||||
* @return true if it exists; false otherwise.
|
||||
*/
|
||||
public boolean containsValue(V value) {
|
||||
return this.reverseMap.containsKey(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key An index key.
|
||||
* @return The value; null if key not indexed.
|
||||
*/
|
||||
public V getValue(K key) {
|
||||
return this.forwardMap.get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A set of all keys; may be empty; never null.
|
||||
*/
|
||||
public Set<K> keySet() {
|
||||
return this.forwardMap.keySet();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A set of all values; may be empty; never null.
|
||||
*/
|
||||
public Set<V> valueSet() {
|
||||
return this.reverseMap.keySet();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param value An indexed value.
|
||||
* @return A set of keys; never empty; null if value not indexed.
|
||||
*/
|
||||
public Set<K> getKeys(V value) {
|
||||
return this.reverseMap.get(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param value An indexed value.
|
||||
* @return The key; null if value not indexed.
|
||||
*/
|
||||
public K getFirstKey(V value) {
|
||||
Set<K> keys = this.reverseMap.get(value);
|
||||
return (keys == null || keys.isEmpty()) ? null : keys.iterator().next();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The number of keys in the index.
|
||||
*/
|
||||
public int size() {
|
||||
return this.forwardMap.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Interable access to the entries of the forward index.
|
||||
*/
|
||||
public Iterable<Entry<K, V>> entries() {
|
||||
return this.forwardMap.entrySet();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key An index key.
|
||||
* @param value A value to index to the specified key.
|
||||
* @return true if the key already existed and was overwritten; false otherwise.
|
||||
*/
|
||||
public synchronized boolean put(K key, V value) {
|
||||
boolean overwrote = false;
|
||||
|
||||
@ -81,6 +154,10 @@ public class Index<K, V> {
|
||||
return overwrote;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key An index key.
|
||||
* @return true if the key and its value were removed; false otherwise.
|
||||
*/
|
||||
public synchronized boolean remove(K key) {
|
||||
V oldValue = this.forwardMap.remove(key);
|
||||
if (oldValue == null)
|
||||
@ -91,6 +168,9 @@ public class Index<K, V> {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method clears/resets the index.
|
||||
*/
|
||||
public synchronized void clear() {
|
||||
this.forwardMap.clear();
|
||||
this.reverseMap.clear();
|
||||
|
@ -1,3 +1,17 @@
|
||||
/*
|
||||
* 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.maven.aps.modeling.util;
|
||||
|
||||
import java.util.Arrays;
|
||||
@ -5,15 +19,41 @@ import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* This class implements a comparator for the value of map keys.
|
||||
*
|
||||
* If key values are considered equal, fallback keys are supported. Any map
|
||||
* without the key or not null value will be considered "greater than" ones
|
||||
* that have values for the specified key. This will move them to the end of
|
||||
* any sorted list.
|
||||
*
|
||||
* @author brian@inteligr8.com
|
||||
*/
|
||||
public class MapComparator<K, V> implements Comparator<Map<K, V>> {
|
||||
|
||||
//private final Logger logger = LoggerFactory.getLogger(ArrayOfObjectNodeComparator.class);
|
||||
private final List<K> keys;
|
||||
|
||||
/**
|
||||
* An array-based constructor.
|
||||
*
|
||||
* The class will sort on the values of these map keys, with a priority in
|
||||
* the specified order.
|
||||
*
|
||||
* @param keys An array of keys.
|
||||
*/
|
||||
public MapComparator(@SuppressWarnings("unchecked") K... keys) {
|
||||
this(Arrays.asList(keys));
|
||||
}
|
||||
|
||||
/**
|
||||
* A list-based constructor.
|
||||
*
|
||||
* The class will sort on the values of these map keys, with a priority in
|
||||
* the specified order.
|
||||
*
|
||||
* @param keys A list of keys.
|
||||
*/
|
||||
public MapComparator(List<K> keys) {
|
||||
this.keys = keys;
|
||||
}
|
||||
|
@ -1,3 +1,17 @@
|
||||
/*
|
||||
* 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.maven.aps.modeling.util;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
@ -40,11 +54,19 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import com.inteligr8.maven.aps.modeling.xml.DomNamespaceContext;
|
||||
|
||||
/**
|
||||
* This singleton class provides JSON and XML I/O tools and consistent formatting.
|
||||
*
|
||||
* @author brian@inteligr8.com
|
||||
*/
|
||||
public class ModelUtil {
|
||||
|
||||
public final static QName CDATA_FLEX = QName.valueOf("inteligr8:xml:cdata_or_element");
|
||||
private final static ModelUtil INSTANCE = new ModelUtil();
|
||||
|
||||
/**
|
||||
* @return A singleton instance of this class.
|
||||
*/
|
||||
public static ModelUtil getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
@ -89,11 +111,42 @@ public class ModelUtil {
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This method reads/parses JSON and immediately formats/writes JSON back
|
||||
* to the specified file.
|
||||
*
|
||||
* You many optionally enable the sorting of elements. Sorting makes the
|
||||
* files more diff-friendly. The algorithm will sort JSON objects by keys.
|
||||
* JSON array values will not be sorted.
|
||||
*
|
||||
* This method will load the full set of JSON objects into memory.
|
||||
*
|
||||
* @param inplaceFile A file handle to an existing valid JSON file.
|
||||
* @param enableSorting true to sort; false to leave as-is.
|
||||
* @throws IOException A file I/O issue occurred.
|
||||
*/
|
||||
public void json(File inplaceFile, boolean enableSorting) throws IOException {
|
||||
JsonNode json = this.readJson(inplaceFile);
|
||||
this.writeJson(json, inplaceFile, enableSorting);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method reads/parses JSON from the specified source file and
|
||||
* immediately formats/writes JSON to the specified target file.
|
||||
*
|
||||
* If the specified target file already exists, it will be overwritten.
|
||||
*
|
||||
* You many optionally enable the sorting of elements. Sorting makes the
|
||||
* files more diff-friendly. The algorithm will sort JSON objects by keys.
|
||||
* JSON array values will not be sorted.
|
||||
*
|
||||
* This method will load the full set of JSON objects into memory.
|
||||
*
|
||||
* @param sourceFile A file handle to an existing valid JSON file.
|
||||
* @param targetFile A file handle for the target JSON file.
|
||||
* @param enableSorting true to sort; false to leave as-is.
|
||||
* @throws IOException A file I/O issue occurred.
|
||||
*/
|
||||
public void json(File sourceFile, File targetFile, boolean enableSorting) throws IOException {
|
||||
FileInputStream fistream = new FileInputStream(sourceFile);
|
||||
BufferedInputStream bistream = new BufferedInputStream(fistream, this.bufferSize);
|
||||
@ -110,16 +163,45 @@ public class ModelUtil {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method reads/parses JSON from the specified source stream and
|
||||
* immediately formats/writes JSON to the specified target stream.
|
||||
*
|
||||
* You many optionally enable the sorting of elements. Sorting makes the
|
||||
* files more diff-friendly. The algorithm will sort JSON objects by keys.
|
||||
* JSON array values will not be sorted.
|
||||
*
|
||||
* This method will load the full set of JSON objects into memory.
|
||||
*
|
||||
* @param istream An input stream to valid JSON.
|
||||
* @param ostream An output stream.
|
||||
* @param enableSorting true to sort; false to leave as-is.
|
||||
* @throws IOException A stream I/O issue occurred.
|
||||
*/
|
||||
public void json(InputStream istream, OutputStream ostream, boolean enableSorting) throws IOException {
|
||||
// FIXME stream it for lower memory/IO usage
|
||||
JsonNode json = this.readJson(istream);
|
||||
this.writeJson(json, ostream, enableSorting);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method reads/parses JSON from the specified file.
|
||||
*
|
||||
* @param file A file handle to an existing valid JSON file.
|
||||
* @return A JSON node (array, object, or value).
|
||||
* @throws IOException A file I/O issue occurred.
|
||||
*/
|
||||
public JsonNode readJson(File file) throws IOException {
|
||||
return this.readJson(file, JsonNode.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method reads/parses JSON from the specified file.
|
||||
*
|
||||
* @param file A file handle to an existing valid JSON file.
|
||||
* @param type A type parse the JSON into (using the Jackson parser).
|
||||
* @return An instance of the specified type.
|
||||
* @throws IOException A file I/O issue occurred.
|
||||
*/
|
||||
public <T> T readJson(File file, Class<T> type) throws IOException {
|
||||
FileInputStream fistream = new FileInputStream(file);
|
||||
BufferedInputStream bistream = new BufferedInputStream(fistream, this.bufferSize);
|
||||
@ -130,6 +212,13 @@ public class ModelUtil {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method reads/parses JSON from the specified file.
|
||||
*
|
||||
* @param file A file handle to an existing valid JSON file.
|
||||
* @return A JSON array as a list.
|
||||
* @throws IOException A file I/O issue occurred.
|
||||
*/
|
||||
public <T> List<T> readJsonAsList(File file) throws IOException {
|
||||
FileInputStream fistream = new FileInputStream(file);
|
||||
BufferedInputStream bistream = new BufferedInputStream(fistream, this.bufferSize);
|
||||
@ -140,6 +229,13 @@ public class ModelUtil {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method reads/parses JSON from the specified file.
|
||||
*
|
||||
* @param file A file handle to an existing valid JSON file.
|
||||
* @return A JSON object as a map.
|
||||
* @throws IOException A file I/O issue occurred.
|
||||
*/
|
||||
public Map<String, Object> readJsonAsMap(File file) throws IOException {
|
||||
FileInputStream fistream = new FileInputStream(file);
|
||||
BufferedInputStream bistream = new BufferedInputStream(fistream, this.bufferSize);
|
||||
@ -150,24 +246,67 @@ public class ModelUtil {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method reads/parses JSON from the specified stream.
|
||||
*
|
||||
* @param istream An input stream to valid JSON.
|
||||
* @return A JSON node (array, object, or value).
|
||||
* @throws IOException A stream I/O issue occurred.
|
||||
*/
|
||||
public JsonNode readJson(InputStream istream) throws IOException {
|
||||
return this.om.readTree(istream);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method reads/parses JSON from the specified stream.
|
||||
*
|
||||
* @param istream An input stream to valid JSON.
|
||||
* @param type A type parse the JSON into (using the Jackson parser).
|
||||
* @return An instance of the specified type.
|
||||
* @throws IOException A stream I/O issue occurred.
|
||||
*/
|
||||
public <T> T readJson(InputStream istream, Class<T> type) throws IOException {
|
||||
return this.om.readValue(istream, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method reads/parses JSON from the specified stream.
|
||||
*
|
||||
* @param istream An input stream to valid JSON.
|
||||
* @return A JSON array as a list.
|
||||
* @throws IOException A stream I/O issue occurred.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> List<T> readJsonAsList(InputStream istream) throws IOException {
|
||||
return this.om.readValue(istream, List.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method reads/parses JSON from the specified stream.
|
||||
*
|
||||
* @param istream An input stream to valid JSON.
|
||||
* @return A JSON object as a map.
|
||||
* @throws IOException A stream I/O issue occurred.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public Map<String, Object> readJsonAsMap(InputStream istream) throws IOException {
|
||||
return this.om.readValue(istream, Map.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method formats/writes JSON to the specified file.
|
||||
*
|
||||
* If the specified file already exists, it will be overwritten.
|
||||
*
|
||||
* You many optionally enable the sorting of elements. Sorting makes the
|
||||
* files more diff-friendly. The algorithm will sort JSON objects by keys.
|
||||
* JSON array values will not be sorted.
|
||||
*
|
||||
* @param json A JSON node (array, object, or value).
|
||||
* @param file A file handle.
|
||||
* @param enableSorting true to sort; false to leave as-is.
|
||||
* @throws IOException A file I/O issue occurred.
|
||||
*/
|
||||
public void writeJson(JsonNode json, File file, boolean enableSorting) throws IOException {
|
||||
FileOutputStream fostream = new FileOutputStream(file);
|
||||
BufferedOutputStream bostream = new BufferedOutputStream(fostream, this.bufferSize);
|
||||
@ -178,6 +317,20 @@ public class ModelUtil {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method formats/writes JSON to the specified file.
|
||||
*
|
||||
* If the specified file already exists, it will be overwritten.
|
||||
*
|
||||
* You many optionally enable the sorting of elements. Sorting makes the
|
||||
* files more diff-friendly. The algorithm will sort JSON objects by keys.
|
||||
* JSON array values will not be sorted.
|
||||
*
|
||||
* @param map A Java map.
|
||||
* @param file A file handle.
|
||||
* @param enableSorting true to sort; false to leave as-is.
|
||||
* @throws IOException A file I/O issue occurred.
|
||||
*/
|
||||
public void writeJson(Map<String, Object> map, File file, boolean enableSorting) throws IOException {
|
||||
FileOutputStream fostream = new FileOutputStream(file);
|
||||
BufferedOutputStream bostream = new BufferedOutputStream(fostream, this.bufferSize);
|
||||
@ -188,6 +341,18 @@ public class ModelUtil {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method formats/writes JSON to the specified file.
|
||||
*
|
||||
* You many optionally enable the sorting of elements. Sorting makes the
|
||||
* files more diff-friendly. The algorithm will sort JSON objects by keys.
|
||||
* JSON array values will not be sorted.
|
||||
*
|
||||
* @param json A JSON node (array, object, or value).
|
||||
* @param ostream An output stream.
|
||||
* @param enableSorting true to sort; false to leave as-is.
|
||||
* @throws IOException A file I/O issue occurred.
|
||||
*/
|
||||
public void writeJson(JsonNode json, OutputStream ostream, boolean enableSorting) throws IOException {
|
||||
if (enableSorting) {
|
||||
this.omsorted.writeValue(ostream, json);
|
||||
@ -196,6 +361,18 @@ public class ModelUtil {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method formats/writes JSON to the specified file.
|
||||
*
|
||||
* You many optionally enable the sorting of elements. Sorting makes the
|
||||
* files more diff-friendly. The algorithm will sort JSON objects by keys.
|
||||
* JSON array values will not be sorted.
|
||||
*
|
||||
* @param map A Java map.
|
||||
* @param ostream An output stream.
|
||||
* @param enableSorting true to sort; false to leave as-is.
|
||||
* @throws IOException A file I/O issue occurred.
|
||||
*/
|
||||
public void writeJson(Map<String, Object> map, OutputStream ostream, boolean enableSorting) throws IOException {
|
||||
if (enableSorting) {
|
||||
this.omsorted.writeValue(ostream, map);
|
||||
@ -206,6 +383,17 @@ public class ModelUtil {
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This method reads/parses XML and immediately formats/writes XML back to
|
||||
* the specified file.
|
||||
*
|
||||
* This method will load the full DOM of XML into memory.
|
||||
*
|
||||
* @param inplaceFile A file handle to an existing valid XML file.
|
||||
* @throws IOException A file I/O issue occurred.
|
||||
* @throws SAXException The file is not valid XML.
|
||||
* @throws TransformerException An unknown XML transformation issue occurred.
|
||||
*/
|
||||
public void xml(File inplaceFile) throws IOException, SAXException, TransformerException {
|
||||
Document xml;
|
||||
|
||||
@ -226,6 +414,20 @@ public class ModelUtil {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method reads/parses XML from the specified source file and
|
||||
* immediately formats/writes XML to to the specified target file.
|
||||
*
|
||||
* If the specified target file already exists, it will be overwritten.
|
||||
*
|
||||
* This method will load the full DOM of XML into memory.
|
||||
*
|
||||
* @param sourceFile A file handle to an existing valid XML file.
|
||||
* @param targetFile A file handle.
|
||||
* @throws IOException A file I/O issue occurred.
|
||||
* @throws SAXException The file is not valid XML.
|
||||
* @throws TransformerException An unknown XML transformation issue occurred.
|
||||
*/
|
||||
public void xml(File sourceFile, File targetFile) throws IOException, SAXException, TransformerException {
|
||||
FileInputStream fistream = new FileInputStream(sourceFile);
|
||||
BufferedInputStream bistream = new BufferedInputStream(fistream, this.bufferSize);
|
||||
@ -242,12 +444,31 @@ public class ModelUtil {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method reads/parses XML from the specified source stream and
|
||||
* immediately formats/writes XML to to the specified target stream.
|
||||
*
|
||||
* This method will load the full DOM of XML into memory.
|
||||
*
|
||||
* @param sourceFile A file handle to an existing valid XML file.
|
||||
* @param targetFile A file handle.
|
||||
* @throws IOException A file I/O issue occurred.
|
||||
* @throws SAXException The file is not valid XML.
|
||||
* @throws TransformerException An unknown XML transformation issue occurred.
|
||||
*/
|
||||
public void xml(InputStream istream, OutputStream ostream) throws IOException, SAXException, TransformerException {
|
||||
// FIXME stream it for lower memory/IO usage
|
||||
Document doc = this.readXml(istream);
|
||||
this.writeXml(doc, ostream);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method reads/parses XML from the specified file.
|
||||
*
|
||||
* @param file A file handle to an existing valid XML file.
|
||||
* @return An XML DOM Document object.
|
||||
* @throws IOException A file I/O issue occurred.
|
||||
* @throws SAXException The file is not valid XML.
|
||||
*/
|
||||
public Document readXml(File file) throws IOException, SAXException {
|
||||
FileInputStream fistream = new FileInputStream(file);
|
||||
BufferedInputStream bistream = new BufferedInputStream(fistream, this.bufferSize);
|
||||
@ -258,10 +479,28 @@ public class ModelUtil {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method reads/parses XML from the specified stream.
|
||||
*
|
||||
* @param istream An input stream to valid XML.
|
||||
* @return An XML DOM Document object.
|
||||
* @throws IOException A stream I/O issue occurred.
|
||||
* @throws SAXException The stream is not valid XML.
|
||||
*/
|
||||
public Document readXml(InputStream istream) throws IOException, SAXException {
|
||||
return this.docBuilder.parse(istream);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method formats/writes XML to the specified file.
|
||||
*
|
||||
* If the specified file already exists, it will be overwritten.
|
||||
*
|
||||
* @param xml An XML element.
|
||||
* @param file A file handle.
|
||||
* @throws IOException A file I/O issue occurred.
|
||||
* @throws TransformerException An unknown XML transformation issue occurred.
|
||||
*/
|
||||
public void writeXml(Node xml, File file) throws IOException, TransformerException {
|
||||
FileOutputStream fostream = new FileOutputStream(file);
|
||||
BufferedOutputStream bostream = new BufferedOutputStream(fostream, this.bufferSize);
|
||||
@ -272,16 +511,43 @@ public class ModelUtil {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method formats/writes XML to the specified stream.
|
||||
*
|
||||
* @param xml An XML element.
|
||||
* @param ostream An output stream.
|
||||
* @throws IOException A stream I/O issue occurred.
|
||||
* @throws TransformerException An unknown XML transformation issue occurred.
|
||||
*/
|
||||
public void writeXml(Node xml, OutputStream ostream) throws IOException, TransformerException {
|
||||
DOMSource source = new DOMSource(xml);
|
||||
StreamResult result = new StreamResult(ostream);
|
||||
this.transformer.transform(source, result);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This method searches the DOM using an XPath expression.
|
||||
*
|
||||
* @param node An XML node.
|
||||
* @param xpathExpr An XPath expression.
|
||||
* @return An XML DOM list of nodes object; null if no result.
|
||||
* @throws XPathExpressionException An unknown XPath issue occurred.
|
||||
*/
|
||||
public NodeList xpath(Node node, String xpathExpr) throws XPathExpressionException {
|
||||
return (NodeList)this.xpath(node, xpathExpr, XPathConstants.NODESET);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method searches the DOM using an XPath expression.
|
||||
*
|
||||
* @param node An XML node.
|
||||
* @param xpathExpr An XPath expression.
|
||||
* @param returnType An XPath return type: see XPathConstants.
|
||||
* @return An XML DOM list of nodes object; null if no result.
|
||||
* @throws XPathExpressionException An unknown XPath issue occurred.
|
||||
*/
|
||||
public Object xpath(Node node, String xpathExpr, QName returnType) throws XPathExpressionException {
|
||||
XPath xpath = this.xpathfactory.newXPath();
|
||||
xpath.setNamespaceContext(new DomNamespaceContext(node));
|
||||
|
@ -1,3 +1,17 @@
|
||||
/*
|
||||
* 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.maven.aps.modeling.util;
|
||||
|
||||
import java.util.Arrays;
|
||||
@ -6,15 +20,45 @@ import java.util.List;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
|
||||
/**
|
||||
* This class implements a comparator for the value of JSON object fields.
|
||||
*
|
||||
* If field values are considered equal, fallback fields are supported. Any
|
||||
* object without the field in question will be considered "greater than" ones
|
||||
* that have the specified field. This will move them to the end of any sorted
|
||||
* list.
|
||||
*
|
||||
* If a JSON value or array is encountered instead of a JSON object, then it is
|
||||
* treated exactly like a JSON object without the specified field. It will be
|
||||
* considered "greater than" and move to the end of any sorted list.
|
||||
*
|
||||
* @author brian@inteligr8.com
|
||||
*/
|
||||
public class ObjectNodeComparator implements Comparator<JsonNode> {
|
||||
|
||||
//private final Logger logger = LoggerFactory.getLogger(ArrayOfObjectNodeComparator.class);
|
||||
private final List<String> objectFieldNames;
|
||||
|
||||
/**
|
||||
* An array-based constructor.
|
||||
*
|
||||
* The class will sort on the values of these JSON object field names, with
|
||||
* a priority in the specified order.
|
||||
*
|
||||
* @param objectFieldNames An array of JSON object field names.
|
||||
*/
|
||||
public ObjectNodeComparator(String... objectFieldNames) {
|
||||
this(Arrays.asList(objectFieldNames));
|
||||
}
|
||||
|
||||
/**
|
||||
* A list-based constructor.
|
||||
*
|
||||
* The class will sort on the values of these JSON object field names, with
|
||||
* a priority in the specified order.
|
||||
*
|
||||
* @param objectFieldNames A list of JSON object field names.
|
||||
*/
|
||||
public ObjectNodeComparator(List<String> objectFieldNames) {
|
||||
this.objectFieldNames = objectFieldNames;
|
||||
}
|
||||
@ -22,9 +66,9 @@ public class ObjectNodeComparator implements Comparator<JsonNode> {
|
||||
@Override
|
||||
public int compare(JsonNode o1, JsonNode o2) {
|
||||
if (!o1.isObject())
|
||||
return -1;
|
||||
if (!o2.isObject())
|
||||
return 1;
|
||||
if (!o2.isObject())
|
||||
return -1;
|
||||
|
||||
for (String objectFieldName : objectFieldNames) {
|
||||
JsonNode value1 = o1.get(objectFieldName);
|
||||
|
@ -1,3 +1,17 @@
|
||||
/*
|
||||
* 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.maven.aps.modeling.xml;
|
||||
|
||||
import java.util.Collections;
|
||||
@ -9,6 +23,9 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
/**
|
||||
* This class implements namespace handling for DOM processing.
|
||||
*/
|
||||
public class DomNamespaceContext implements NamespaceContext {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(DomNamespaceContext.class);
|
||||
@ -16,10 +33,22 @@ public class DomNamespaceContext implements NamespaceContext {
|
||||
private final String defaultNamespacePrefix;
|
||||
private final String defaultNamespace;
|
||||
|
||||
/**
|
||||
* The constructor using just a DOM node. The default namespace prefix is
|
||||
* assumed to be 'tns'.
|
||||
*
|
||||
* @param node A DOM node.
|
||||
*/
|
||||
public DomNamespaceContext(Node node) {
|
||||
this(node, "tns");
|
||||
}
|
||||
|
||||
/**
|
||||
* The constructor using just a DOM node.
|
||||
*
|
||||
* @param node A DOM node.
|
||||
* @param defaultNamespacePrefix A DOM namespace prefix.
|
||||
*/
|
||||
public DomNamespaceContext(Node node, String defaultNamespacePrefix) {
|
||||
this.node = node;
|
||||
this.defaultNamespacePrefix = defaultNamespacePrefix;
|
||||
|
Loading…
x
Reference in New Issue
Block a user