提交 cd40d245 编写于 作者: B bernd.ruecker

added "create maven project" action with template, fixed bug with folder...

added "create maven project" action with template, fixed bug with folder creation in FileSystemConnector, made ID names in Developer friendly BPMN more robust
上级 3984a7da
package org.activiti.cycle;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import org.activiti.engine.impl.util.IoUtil;
......@@ -27,25 +25,9 @@ public class Content {
private InputStream contentAsInputStream;
private byte[] loadBytes(InputStream inputStream) {
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
try {
byte[] buf = new byte[512];
int len;
while (true) {
len = inputStream.read(buf);
if (len == -1) {
break;
}
byteStream.write(buf, 0, len);
}
return byteStream.toByteArray();
} catch (IOException ex) {
throw new RepositoryException("Couldn't load from InputStream of content, check nested exception.", ex);
} finally {
// Close inputstream. Closing of ByteArrayOutputStream not nessecairy, does nothing
IoUtil.closeSilently(inputStream);
}
byte[] bytes = IoUtil.readInputStream(inputStream, "Repository Artifact Content");
IoUtil.closeSilently(inputStream);
return bytes;
}
public byte[] asByteArray() {
......@@ -90,16 +72,22 @@ public class Content {
public void setValue(String text) {
this.contentAsString = text;
this.contentAsByteArray = null;
this.contentAsInputStream = null;
}
public void setValue(byte[] content) {
this.contentAsString = null;
this.contentAsByteArray = content;
this.contentAsInputStream = null;
}
/**
* TODO: When can we close that stream? How do we now we are done?
*/
public void setValue(InputStream stream) {
this.contentAsString = null;
this.contentAsByteArray = null;
this.contentAsInputStream = stream;
}
......
......@@ -29,9 +29,12 @@ public abstract class ParameterizedHtmlFormTemplateAction extends ParameterizedA
* class name + ".html" in the same package as the class
*/
public String getDefaultFormName() {
return "/" + this.getClass().getName().replace(".", "/") + ".html";
return getFormNameForClass(this.getClass());
}
public String getFormNameForClass(Class clazz) {
return "/" + clazz.getName().replace(".", "/") + ".html";
}
public String getFormAsHtml() {
InputStream is = null;
......
......@@ -104,9 +104,9 @@ public class FileSystemConnector extends AbstractRepositoryConnector<FileSystemC
}
public RepositoryFolder createFolder(String parentFolderId, String name) throws RepositoryNodeNotFoundException {
File newSubFolder = new File(getFileFromId(parentFolderId), parentFolderId);
File newSubFolder = new File(getFileFromId(parentFolderId), name);
if (!newSubFolder.mkdir()) {
throw new RepositoryException("Unable to create subfolder " + parentFolderId + " in parentfolder " + parentFolderId);
throw new RepositoryException("Unable to create subfolder '" + name + "' in parentfolder '" + parentFolderId + "'");
}
return getRepositoryFolder(getRepositoryNodeId(parentFolderId, name));
......
......@@ -9,6 +9,7 @@ import org.activiti.cycle.impl.ArtifactTypeImpl;
import org.activiti.cycle.impl.ContentRepresentationImpl;
import org.activiti.cycle.impl.conf.RepositoryConnectorConfiguration;
import org.activiti.cycle.impl.connector.signavio.action.CopySignavioModelAction;
import org.activiti.cycle.impl.connector.signavio.action.CreateMavenProjectAction;
import org.activiti.cycle.impl.connector.signavio.action.CreateTechnicalBpmnXmlAction;
import org.activiti.cycle.impl.connector.signavio.action.OpenModelerAction;
import org.activiti.cycle.impl.connector.signavio.action.SelectDiffTargetAction;
......@@ -80,6 +81,7 @@ public class SignavioPluginDefinition implements ActivitiCyclePluginDefinition {
artifactType1.addParameterizedAction(new ValidateActivitiDeployment());
artifactType1.addParameterizedAction(new CopySignavioModelAction());
artifactType1.addParameterizedAction(new SelectDiffTargetAction());
artifactType1.addParameterizedAction(new CreateMavenProjectAction());
artifactType1.addOpenUrlAction(new OpenModelerAction());
artifactType1.addDownloadContentAction(CONTENT_REPRESENTATION_ID_BPMN_20_DEVELOPER);
artifactType1.addDownloadContentAction(CONTENT_REPRESENTATION_ID_BPMN_20_RAW);
......
package org.activiti.cycle.impl.connector.signavio.action;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.logging.Level;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.activiti.cycle.Content;
import org.activiti.cycle.RepositoryArtifact;
import org.activiti.cycle.RepositoryConnector;
import org.activiti.cycle.RepositoryException;
import org.activiti.engine.impl.util.IoUtil;
public class CreateMavenProjectAction extends CreateTechnicalBpmnXmlAction {
private static final long serialVersionUID = 1L;
public static final String PARAM_TARGET_FOLDER = "targetFolderId";
public static final String PARAM_TARGET_CONNECTOR = "targetConnectorId";
public static final String PARAM_TARGET_NAME = "targetName";
public static final String PARAM_COMMENT = "comment";
public static final String CREATE_LINK_NAME = "createLink";
private static final String REPLACE_STRING = "activiti.project.template";
public CreateMavenProjectAction() {
// TODO: remove when real labels are introduced in the GUI
super("Create default maven project");
}
public void execute(RepositoryConnector connector, RepositoryArtifact artifact, Map<String, Object> parameters) throws Exception {
String targetFolderId = (String) getParameter(parameters, PARAM_TARGET_FOLDER, true, null, String.class);
String targetName = (String) getParameter(parameters, PARAM_TARGET_NAME, false, getProcessName(artifact), String.class);
String comment = (String) getParameter(parameters, PARAM_COMMENT, false, null, String.class);
RepositoryConnector targetConnector = (RepositoryConnector) getParameter(parameters, PARAM_TARGET_CONNECTOR, true, null, RepositoryConnector.class);
boolean createLink = (Boolean) getParameter(parameters, CREATE_LINK_NAME, true, Boolean.TRUE, Boolean.class);
createProject(targetConnector, targetFolderId, targetName, createBpmnXml(connector, artifact));
// TODO: Think about that more, does it make sense like this?
targetConnector.commitPendingChanges(comment);
if (createLink) {
// TODO: We cannot link to a folder at the moment!
// RepositoryFolder targetFolder =
// targetConnector.getRepositoryFolder(targetFolderId);
// RepositoryArtifactLink link = new RepositoryArtifactLinkEntity();
// link.setSourceArtifact(artifact);
// link.setTargetArtifact(targetFolder);
// link.setComment(comment);
// link.setLinkType(getLinkType());
// connector.getConfiguration().getCycleService().addArtifactLink(link);
}
}
public String getProcessName(RepositoryArtifact artifact) {
return artifact.getMetadata().getName();
}
@Override
public String getFormResourceName() {
return getFormNameForClass(CreateTechnicalBpmnXmlAction.class);
}
public void createProject(RepositoryConnector connector, String rootFolderId, String projectName, String processDefinitionXml) {
try {
ZipInputStream projectTemplateInputStream = new ZipInputStream(getProjectTemplate());
ZipEntry zipEntry = null;
String rootSubstitution = null;
while ((zipEntry = projectTemplateInputStream.getNextEntry()) != null) {
String zipName = zipEntry.getName();
if (zipName.endsWith("/")) {
zipName = zipName.substring(0, zipName.length() - 1);
}
String path = "";
String name = zipName;
if (zipName.contains("/")) {
path = zipName.substring(0, zipName.lastIndexOf("/"));
name = zipName.substring(zipName.lastIndexOf("/") + 1);
}
if ("".equals(path)) {
// root folder is named after the project, not like the template
// folder name
rootSubstitution = name;
name = projectName;
}
else {
// rename the root folder in all other paths as well
path = path.replace(rootSubstitution, projectName);
}
String absolutePath = rootFolderId + "/" + path;
if (zipEntry.isDirectory()) {
connector.createFolder(absolutePath, name);
} else {
Content content = new Content();
if ("template.bpmn20.xml".equals(name)) {
// This file shall be replaced with the process definition
content.setValue(processDefinitionXml);
name = projectName + ".bpmn20.xml";
log.log(Level.INFO, "Create processdefinition from Signavio process model " + projectName);
} else {
byte[] bytes = IoUtil.readInputStream(projectTemplateInputStream, "ZIP entry '" + zipName + "'");
String txtContent = new String(bytes).replaceAll(REPLACE_STRING, projectName);
content.setValue(txtContent);
}
log.log(Level.INFO, "Create new artifact from zip entry '" + zipEntry.getName() + "' in folder '" + absolutePath + "' with name '" + name + "'");
connector.createArtifact(absolutePath, name, null, content);
}
projectTemplateInputStream.closeEntry();
}
projectTemplateInputStream.close();
} catch (IOException ex) {
throw new RepositoryException("Couldn't create maven project due to IO errors", ex);
}
}
protected InputStream getProjectTemplate() {
return this.getClass().getResourceAsStream("activiti-cycle-maven-template.zip");
}
}
package org.activiti.cycle.impl.connector.signavio.action;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.activiti.cycle.Content;
import org.activiti.cycle.RepositoryArtifact;
import org.activiti.cycle.RepositoryArtifactLink;
import org.activiti.cycle.RepositoryConnector;
import org.activiti.cycle.RepositoryException;
import org.activiti.cycle.RepositoryFolder;
import org.activiti.cycle.impl.ParameterizedHtmlFormTemplateAction;
import org.activiti.cycle.impl.connector.fs.FileSystemPluginDefinition;
import org.activiti.cycle.impl.connector.signavio.SignavioConnector;
import org.activiti.cycle.impl.connector.signavio.SignavioPluginDefinition;
import org.activiti.cycle.impl.connector.signavio.util.SignavioTransformationHelper;
import org.activiti.cycle.impl.db.entity.RepositoryArtifactLinkEntity;
import org.activiti.cycle.impl.transform.JsonTransformation;
import org.activiti.cycle.impl.transform.signavio.AdjustShapeNamesTransformation;
import org.activiti.cycle.impl.transform.signavio.BpmnPoolExtraction;
import org.activiti.cycle.impl.transform.signavio.ExchangeSignavioUuidWithNameTransformation;
import org.activiti.cycle.impl.transform.signavio.RemedyTemporarySignavioIncompatibilityTransformation;
import org.json.JSONObject;
/**
* This action creates a technical BPMN 2.0 XML for the process engines. It
......@@ -41,22 +34,6 @@ public class CreateTechnicalBpmnXmlAction extends ParameterizedHtmlFormTemplateA
public static final String PARAM_COMMENT = "comment";
public static final String CREATE_LINK_NAME = "createLink";
/**
* Where do we get the transformations from? How are they registered?
*
* How can we extend that project specific?
*/
public static List<JsonTransformation> registeredTransformations = new ArrayList<JsonTransformation>();
static {
// TODO: How to register JSON-Transformations
// example with cutting out just the Engine Pool
addTransformation(new BpmnPoolExtraction("Process Engine"));
addTransformation(new ExchangeSignavioUuidWithNameTransformation());
addTransformation(new AdjustShapeNamesTransformation());
}
public CreateTechnicalBpmnXmlAction() {
// TODO: remove when real labels are introduced in the GUI
super("Create technical model");
......@@ -67,10 +44,6 @@ public class CreateTechnicalBpmnXmlAction extends ParameterizedHtmlFormTemplateA
super(name);
}
public static void addTransformation(JsonTransformation transformation) {
registeredTransformations.add(transformation);
}
public void execute(RepositoryConnector connector, RepositoryArtifact artifact, Map<String, Object> parameters) throws Exception {
// TODO: Check with Nils that we get the object instead of the string in
// here!
......@@ -101,30 +74,21 @@ public class CreateTechnicalBpmnXmlAction extends ParameterizedHtmlFormTemplateA
public RepositoryArtifact createArtifact(RepositoryConnector connector, RepositoryArtifact artifact, String targetFolderId, String targetName,
RepositoryConnector targetConnector) throws Exception {
String sourceJson = getBpmn20Json((SignavioConnector) connector, artifact);
String transformedJson = applyJsonTransformations(sourceJson);
String bpmnXml = transformToBpmn20((SignavioConnector) connector, transformedJson);
String bpmnXml = createBpmnXml(connector, artifact);
RepositoryArtifact targetArtifact = createTargetArtifact(targetConnector, targetFolderId, targetName + ".bpmn20.xml", bpmnXml,
FileSystemPluginDefinition.ARTIFACT_TYPE_BPMN_20_XML);
return targetArtifact;
}
protected String getBpmn20Json(RepositoryConnector connector, RepositoryArtifact artifact) {
return connector.getContent(artifact.getNodeId(), SignavioPluginDefinition.CONTENT_REPRESENTATION_ID_JSON).asString();
public String createBpmnXml(RepositoryConnector connector, RepositoryArtifact artifact) {
String sourceJson = getBpmn20Json((SignavioConnector) connector, artifact);
String transformedJson = SignavioTransformationHelper.applyJsonTransformations(sourceJson);
String bpmnXml = transformToBpmn20((SignavioConnector) connector, transformedJson);
return bpmnXml;
}
protected String applyJsonTransformations(String sourceJson) {
try {
JSONObject jsonObject = new JSONObject(sourceJson);
for (JsonTransformation trafo : registeredTransformations) {
jsonObject = trafo.transform(jsonObject);
}
return jsonObject.toString();
} catch (Exception e) {
throw new RepositoryException("Exception occured while transformation of BPMN model", e);
}
protected String getBpmn20Json(RepositoryConnector connector, RepositoryArtifact artifact) {
return connector.getContent(artifact.getNodeId(), SignavioPluginDefinition.CONTENT_REPRESENTATION_ID_JSON).asString();
}
protected String transformToBpmn20(SignavioConnector connector, String transformedJson) {
......
......@@ -34,9 +34,7 @@ public class ValidateActivitiDeployment extends CreateTechnicalBpmnXmlAction {
.getProcessEngineConfiguration();
ExpressionManager expressionManager = processEngineConfiguration.getExpressionManager();
String sourceJson = getBpmn20Json((SignavioConnector) connector, artifact);
String transformedJson = applyJsonTransformations(sourceJson);
String bpmnXml = transformToBpmn20((SignavioConnector) connector, transformedJson);
String bpmnXml = createBpmnXml((SignavioConnector) connector, artifact);
BpmnParser bpmnParser = new BpmnParser(expressionManager);
......
package org.activiti.cycle.impl.connector.signavio.util;
import java.util.ArrayList;
import java.util.List;
import org.activiti.cycle.RepositoryException;
import org.activiti.cycle.impl.transform.JsonTransformation;
import org.activiti.cycle.impl.transform.signavio.AdjustShapeNamesTransformation;
import org.activiti.cycle.impl.transform.signavio.BpmnPoolExtraction;
import org.activiti.cycle.impl.transform.signavio.ExchangeSignavioUuidWithNameTransformation;
import org.json.JSONObject;
public class SignavioTransformationHelper {
static {
registeredTransformations = new ArrayList<JsonTransformation>();
// TODO: How to register JSON-Transformations
// example with cutting out just the Engine Pool
addTransformation(new BpmnPoolExtraction("Process Engine"));
addTransformation(new ExchangeSignavioUuidWithNameTransformation());
addTransformation(new AdjustShapeNamesTransformation());
}
/**
* Where do we get the transformations from? How are they registered?
*
* How can we extend that project specific?
*/
public static List<JsonTransformation> registeredTransformations;
public static void addTransformation(JsonTransformation transformation) {
registeredTransformations.add(transformation);
}
public static List<JsonTransformation> getRegisteredTransformations() {
return registeredTransformations;
}
public static String applyJsonTransformations(String sourceJson) {
try {
JSONObject jsonObject = new JSONObject(sourceJson);
for (JsonTransformation trafo : getRegisteredTransformations()) {
jsonObject = trafo.transform(jsonObject);
}
return jsonObject.toString();
} catch (Exception e) {
throw new RepositoryException("Exception occured while transformation of BPMN model", e);
}
}
}
package org.activiti.cycle.impl.transform.signavio;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
......@@ -17,8 +15,6 @@ import org.oryxeditor.server.diagram.Shape;
*/
public class ExchangeSignavioUuidWithNameTransformation extends OryxTransformation {
private static final String TASK_NAME = "Task";
@Override
public Diagram transform(Diagram diagram) {
Set<String> existingNames = new HashSet<String>();
......@@ -29,15 +25,11 @@ public class ExchangeSignavioUuidWithNameTransformation extends OryxTransformati
}
private void adjustShapeNames(List<Shape> shapes, Set<String> existingNames) {
for (Shape shape : shapes) {
for (Shape shape : shapes) {
// TODO: Check which exact stencil sets we need to change
String name = null;
String name = null;
if (shape.getProperty("name") != null && shape.getProperty("name").length() > 0) {
// shape.getStencil()!= null &&/
// TASK_NAME.equals(shape.getStencil().getId())
name = shape.getProperty("name");
} else {
name = shape.getStencilId();
}
......@@ -62,28 +54,14 @@ public class ExchangeSignavioUuidWithNameTransformation extends OryxTransformati
}
/**
* adjust name from Signavio (remove new lines, ' and maybe add more in
* future) See https://app.camunda.com/jira/browse/HEMERA-164.
*
* Since that makes problems (see
* http://forums.activiti.org/en/viewtopic.php?f=4&t=259&p=917) we changed to
* proper encoding, even if that is less developer friendly.
*
* TODO: Improve encoding / readability
*
* TODO: Should we have this as own pattern?
* adjust name from Signavio (remove all non special characters to avoid
* possible problems). See e.g.
* http://forums.activiti.org/en/viewtopic.php?f=4&t=259&p=917
*/
public static String adjustNamesForEngine(String name) {
if (name == null) {
return null;
}
try {
return URLEncoder.encode(name.replace(' ', '_'), "UTF-8");
} catch (UnsupportedEncodingException e) {
// Should never happen :-)
throw new IllegalStateException("Wired, platform couldn't encode UTF-8", e);
}
// return name.replaceAll("\n", " ").replaceAll("'", "").replaceAll("\"",
// "");
return name.replaceAll("[^a-zA-Z0-9-]", "_");
}
}
package org.activiti.cycle.impl.transform.signavio;
import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
......@@ -9,9 +9,8 @@ public class ExchangeSignavioUuidWithNameTransformationTest {
@Test
public void testAdjustNamesForEngine() {
String name = "Send rejection e-mail";
String actual = ExchangeSignavioUuidWithNameTransformation.adjustNamesForEngine(name);
assertEquals("Send_rejection_e-mail", actual);
assertEquals("Send_rejection_e-mail", ExchangeSignavioUuidWithNameTransformation.adjustNamesForEngine("Send rejection e-mail"));
assertEquals("_15__everything_mine__-_", ExchangeSignavioUuidWithNameTransformation.adjustNamesForEngine("15: everything mine :-)"));
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册