diff --git a/api/kogito-api/src/main/java/org/kie/kogito/process/workitem/TaskModel.java b/api/kogito-api/src/main/java/org/kie/kogito/process/workitem/TaskModel.java new file mode 100644 index 00000000000..72471169762 --- /dev/null +++ b/api/kogito-api/src/main/java/org/kie/kogito/process/workitem/TaskModel.java @@ -0,0 +1,33 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.kie.kogito.process.workitem; + +public interface TaskModel { + + String getId(); + + String getName(); + + int getState(); + + String getPhase(); + + String getPhaseStatus(); + + P getParams(); + + R getResults(); +} diff --git a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/UserTaskModelMetaData.java b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/UserTaskModelMetaData.java index 18b485b7453..325651faa10 100644 --- a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/UserTaskModelMetaData.java +++ b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/UserTaskModelMetaData.java @@ -34,10 +34,12 @@ import com.github.javaparser.ast.CompilationUnit; import com.github.javaparser.ast.Modifier; +import com.github.javaparser.ast.Node; import com.github.javaparser.ast.NodeList; import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; import com.github.javaparser.ast.body.FieldDeclaration; import com.github.javaparser.ast.body.MethodDeclaration; +import com.github.javaparser.ast.body.Parameter; import com.github.javaparser.ast.body.VariableDeclarator; import com.github.javaparser.ast.comments.LineComment; import com.github.javaparser.ast.expr.AssignExpr; @@ -51,9 +53,14 @@ import com.github.javaparser.ast.expr.StringLiteralExpr; import com.github.javaparser.ast.expr.ThisExpr; import com.github.javaparser.ast.expr.VariableDeclarationExpr; +import com.github.javaparser.ast.nodeTypes.NodeWithType; +import com.github.javaparser.ast.nodeTypes.NodeWithVariables; import com.github.javaparser.ast.stmt.BlockStmt; +import com.github.javaparser.ast.stmt.BreakStmt; import com.github.javaparser.ast.stmt.ReturnStmt; +import com.github.javaparser.ast.stmt.SwitchEntry; import com.github.javaparser.ast.type.ClassOrInterfaceType; +import com.github.javaparser.ast.type.Type; import static com.github.javaparser.StaticJavaParser.parse; import static com.github.javaparser.StaticJavaParser.parseClassOrInterfaceType; @@ -65,6 +72,7 @@ public class UserTaskModelMetaData { private static final String TASK_INTPUT_CLASS_SUFFIX = "TaskInput"; private static final String TASK_OUTTPUT_CLASS_SUFFIX = "TaskOutput"; + private static final String TASK_MODEL_CLASS_SUFFIX = "TaskModel"; private static final String TASK_NAME = "TaskName"; private static final String WORK_ITEM = "workItem"; private static final String PARAMS = "params"; @@ -84,6 +92,9 @@ public class UserTaskModelMetaData { private String outputModelClassName; private String outputModelClassSimpleName; + private String taskModelClassName; + private String taskModelClassSimpleName; + public UserTaskModelMetaData(String packageName, VariableScope processVariableScope, VariableScope variableScope, HumanTaskNode humanTaskNode, String processId) { this.packageName = packageName; this.processVariableScope = processVariableScope; @@ -97,6 +108,9 @@ public UserTaskModelMetaData(String packageName, VariableScope processVariableSc this.outputModelClassSimpleName = ucFirst(ProcessToExecModelGenerator.extractProcessId(processId) + "_" + humanTaskNode.getId() + "_" + TASK_OUTTPUT_CLASS_SUFFIX); this.outputModelClassName = packageName + '.' + outputModelClassSimpleName; + this.taskModelClassSimpleName = ucFirst(ProcessToExecModelGenerator.extractProcessId(processId) + "_" + humanTaskNode.getId() + "_" + TASK_MODEL_CLASS_SUFFIX); + this.taskModelClassName = packageName + '.' + taskModelClassSimpleName; + } public String generateInput() { @@ -109,36 +123,21 @@ public String generateOutput() { return modelClass.toString(); } - public String getInputModelClassName() { - return inputModelClassName; - } - - public void setInputModelClassName(String inputModelClassName) { - this.inputModelClassName = inputModelClassName; - } - - public String getInputModelClassSimpleName() { - return inputModelClassSimpleName; + public String generateModel() { + CompilationUnit modelClass = compilationUnitModel(); + return modelClass.toString(); } - public void setInputModelClassSimpleName(String inputModelClassSimpleName) { - this.inputModelClassSimpleName = inputModelClassSimpleName; + public String getInputModelClassName() { + return inputModelClassName; } public String getOutputModelClassName() { return outputModelClassName; } - public void setOutputModelClassName(String outputModelClassName) { - this.outputModelClassName = outputModelClassName; - } - - public String getOutputModelClassSimpleName() { - return outputModelClassSimpleName; - } - - public void setOutputModelClassSimpleName(String outputModelClassSimpleName) { - this.outputModelClassSimpleName = outputModelClassSimpleName; + public String getTaskModelClassName() { + return taskModelClassName; } public String getName() { @@ -187,21 +186,6 @@ private CompilationUnit compilationUnitInput() { VariableDeclarationExpr itemField = new VariableDeclarationExpr(modelType, "item"); staticFromMap.addStatement(new AssignExpr(itemField, new ObjectCreationExpr(null, modelType, NodeList.nodeList()), AssignExpr.Operator.ASSIGN)); NameExpr item = new NameExpr("item"); - FieldAccessExpr idField = new FieldAccessExpr(item, "_id"); - staticFromMap.addStatement(new AssignExpr(idField, new MethodCallExpr( - new NameExpr(WORK_ITEM), "getId"), AssignExpr.Operator.ASSIGN)); - - FieldAccessExpr nameField = new FieldAccessExpr(item, "_name"); - staticFromMap.addStatement(new AssignExpr(nameField, new MethodCallExpr( - new NameExpr(WORK_ITEM), "getName"), AssignExpr.Operator.ASSIGN)); - - ClassOrInterfaceType toMap = new ClassOrInterfaceType(null, new SimpleName(Map.class.getSimpleName()), - NodeList.nodeList(new ClassOrInterfaceType(null, String.class.getSimpleName()), new ClassOrInterfaceType( - null, - Object.class.getSimpleName()))); - VariableDeclarationExpr paramsField = new VariableDeclarationExpr(toMap, PARAMS); - staticFromMap.addStatement(new AssignExpr(paramsField, new MethodCallExpr( - new NameExpr(WORK_ITEM), "getParameters"), AssignExpr.Operator.ASSIGN)); for (Entry entry : humanTaskNode.getInMappings().entrySet()) { @@ -268,7 +252,7 @@ private CompilationUnit compilationUnitInput() { AssignExpr.Operator.ASSIGN)); } Optional staticFromMethod = modelClass.findFirst( - MethodDeclaration.class, sl -> sl.getName().asString().equals("from") && sl.isStatic()); + MethodDeclaration.class, sl -> sl.getName().asString().equals("fromMap") && sl.isStatic()); if (staticFromMethod.isPresent()) { MethodDeclaration from = staticFromMethod.get(); from.setType(modelClass.getNameAsString()); @@ -367,8 +351,62 @@ private CompilationUnit compilationUnitOutput() { return compilationUnit; } + private CompilationUnit compilationUnitModel() { + CompilationUnit compilationUnit = parse(this.getClass().getResourceAsStream( + "/class-templates/TaskModelTemplate.java")); + compilationUnit.setPackageDeclaration(packageName); + ClassOrInterfaceDeclaration modelClass = compilationUnit + .findFirst(ClassOrInterfaceDeclaration.class, sl1 -> true).orElseThrow(() -> new IllegalStateException( + "Cannot find class declaration in the template")); + compilationUnit.addOrphanComment(new LineComment("Task model for user task '" + humanTaskNode.getName() + + "' in process '" + processId + "'")); + modelClass.setName(taskModelClassSimpleName); + modelClass.getImplementedTypes().forEach(t -> t + .setTypeArguments( + NodeList.nodeList(parseClassOrInterfaceType(inputModelClassName), parseClassOrInterfaceType( + outputModelClassName)))); + modelClass.findAll(NameExpr.class).forEach(this::templateReplacement); + modelClass.findAll(VariableDeclarationExpr.class).forEach(this::templateReplacement); + modelClass.findAll(FieldDeclaration.class).forEach(this::templateReplacement); + modelClass.findAll(ObjectCreationExpr.class).forEach(this::templateReplacement); + modelClass.findAll(MethodDeclaration.class).forEach(this::templateReplacement); + modelClass.findAll(Parameter.class).forEach(this::templateReplacement); + return compilationUnit; + } + + private void templateReplacement(NameExpr name) { + name.setName(templateReplacement(name.getNameAsString())); + } + + private void templateReplacement(NodeWithType expr) { + expr.setType(templateReplacement(expr.getTypeAsString())); + } + + private void templateReplacement(NodeWithVariables expr) { + for (VariableDeclarator variable : expr.getVariables()) { + variable.setType(templateReplacement(variable.getTypeAsString())); + } + } + + public String templateReplacement(String template) { + template = template.replace("$TaskInput$", inputModelClassName); + template = template.replace("$TaskOutput$", outputModelClassName); + template = template.replace("$TaskModel$", taskModelClassName); + return template; + } + public boolean isAdHoc() { return !Boolean.parseBoolean((String) humanTaskNode.getMetaData(CUSTOM_AUTO_START)) && (humanTaskNode.getIncomingConnections() == null || humanTaskNode.getIncomingConnections().isEmpty()); } + + public SwitchEntry getModelSwitchEntry() { + SwitchEntry entry = new SwitchEntry(); + entry.setLabels(NodeList.nodeList(new StringLiteralExpr(getName()))); + entry.addStatement(new AssignExpr(new NameExpr("taskModel"), new MethodCallExpr(new NameExpr( + taskModelClassSimpleName), new SimpleName("from")).addArgument(WORK_ITEM), AssignExpr.Operator.ASSIGN)); + // yes, thats silly, but if not empty string is not specified parser generates break empty or error + entry.addStatement(new BreakStmt(" ")); + return entry; + } } diff --git a/jbpm/jbpm-flow-builder/src/main/resources/class-templates/TaskInputTemplate.java b/jbpm/jbpm-flow-builder/src/main/resources/class-templates/TaskInputTemplate.java index a0baf0b0d35..e071c46f2e5 100644 --- a/jbpm/jbpm-flow-builder/src/main/resources/class-templates/TaskInputTemplate.java +++ b/jbpm/jbpm-flow-builder/src/main/resources/class-templates/TaskInputTemplate.java @@ -20,26 +20,7 @@ public class XXXTaskInput { - private String _id; - private String _name; - - public void setId(String id) { - this._id = id; - } - - public String getId() { - return this._id; - } - - public void setName(String name) { - this._name = name; - } - - public String getName() { - return this._name; - } - - public static XXXTaskInput from(org.kie.kogito.process.WorkItem workItem) { + public static XXXTaskInput fromMap (Map params) { } } \ No newline at end of file diff --git a/jbpm/jbpm-flow-builder/src/main/resources/class-templates/TaskModelTemplate.java b/jbpm/jbpm-flow-builder/src/main/resources/class-templates/TaskModelTemplate.java new file mode 100644 index 00000000000..fbd5115b9cc --- /dev/null +++ b/jbpm/jbpm-flow-builder/src/main/resources/class-templates/TaskModelTemplate.java @@ -0,0 +1,98 @@ +/* + * Copyright 2019 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jbpm.process.codegen; + +import org.kie.kogito.process.workitem.TaskModel; + +public class $TaskModel$ implements TaskModel<$TaskInput$, $TaskOutput$>{ + + private String id; + private String name; + private int state; + private String phase; + private String phaseStatus; + private $TaskInput$ params; + private $TaskOutput$ results; + + + public void setId(String id) { + this.id = id; + } + + public String getId() { + return id; + } + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public int getState() { + return state; + } + + public void setState (int state) { + this.state = state; + } + + public String getPhase() { + return phase; + } + + public void setPhase (String phase) { + this.phase = phase; + } + + public String getPhaseStatus() { + return phaseStatus; + } + + public void setPhaseStatus (String phaseStatus) { + this.phaseStatus = phaseStatus; + } + + public $TaskInput$ getParams () { + return params; + } + + public void setParams ($TaskInput$ params) { + this.params = params; + } + + public $TaskOutput$ getResults () { + return results; + } + + public void setParams ($TaskOutput$ results) { + this.results = results; + } + + public static $TaskModel$ from(org.kie.kogito.process.WorkItem workItem) { + $TaskModel$ taskModel = new $TaskModel$(); + taskModel.id= workItem.getId(); + taskModel.name = workItem.getName(); + taskModel.state = workItem.getState(); + taskModel.phaseStatus = workItem.getPhaseStatus(); + taskModel.phase = workItem.getPhase(); + taskModel.params = $TaskInput$.fromMap(workItem.getParameters()); + taskModel.results = $TaskOutput$.fromMap(workItem.getResults()); + return taskModel; + } +} \ No newline at end of file diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessCodegen.java b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessCodegen.java index 7f5908ce2ba..69146853e3f 100644 --- a/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessCodegen.java +++ b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessCodegen.java @@ -358,6 +358,8 @@ public Collection generate() { storeFile(MODEL_TYPE, UserTasksModelClassGenerator.generatedFilePath(ut.getInputModelClassName()), ut.generateInput()); storeFile(MODEL_TYPE, UserTasksModelClassGenerator.generatedFilePath(ut.getOutputModelClassName()), ut.generateOutput()); + + storeFile(MODEL_TYPE, UserTasksModelClassGenerator.generatedFilePath(ut.getTaskModelClassName()), ut.generateModel()); } } @@ -365,6 +367,11 @@ public Collection generate() { for (ProcessResourceGenerator resourceGenerator : rgs) { storeFile(REST_TYPE, resourceGenerator.generatedFilePath(), resourceGenerator.generate()); + + if (resourceGenerator.hasUserTask()) { + storeFile(MODEL_TYPE, UserTasksModelClassGenerator.generatedFilePath(resourceGenerator.getTaskModelFactoryClassName()), resourceGenerator.getTaskModelFactory()); + } + } } diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessResourceGenerator.java b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessResourceGenerator.java index b1a6623c543..506b70b2e36 100644 --- a/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessResourceGenerator.java +++ b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessResourceGenerator.java @@ -25,6 +25,7 @@ import java.util.stream.Collectors; import org.drools.core.util.StringUtils; +import org.jbpm.compiler.canonical.ProcessToExecModelGenerator; import org.jbpm.compiler.canonical.UserTaskModelMetaData; import org.kie.kogito.codegen.api.context.KogitoBuildContext; import org.kie.kogito.codegen.api.context.impl.QuarkusKogitoBuildContext; @@ -48,9 +49,12 @@ import com.github.javaparser.ast.expr.SimpleName; import com.github.javaparser.ast.expr.StringLiteralExpr; import com.github.javaparser.ast.stmt.BlockStmt; +import com.github.javaparser.ast.stmt.SwitchStmt; import com.github.javaparser.ast.type.ClassOrInterfaceType; import com.github.javaparser.ast.type.Type; +import static com.github.javaparser.StaticJavaParser.parse; +import static org.drools.core.util.StringUtils.ucFirst; import static org.kie.kogito.codegen.core.CodegenUtils.interpolateTypes; /** @@ -79,6 +83,8 @@ public class ProcessResourceGenerator { private boolean dynamic; private List userTasks; private Map signals; + private CompilationUnit taskModelFactoryUnit; + private String taskModelFactoryClassName; public ProcessResourceGenerator( KogitoBuildContext context, @@ -115,6 +121,14 @@ public ProcessResourceGenerator withTriggers(boolean startable, boolean dynamic) return this; } + public String getTaskModelFactory() { + return taskModelFactoryUnit.toString(); + } + + public String getTaskModelFactoryClassName() { + return taskModelFactoryClassName; + } + public String className() { return resourceClazzName; } @@ -202,6 +216,10 @@ public String generate() { // endpoints are not security annotated as they should restrict access based on user assignments securityAnnotated(template); + Map typeInterpolations = new HashMap<>(); + typeInterpolations.put("$Clazz$", resourceClazzName); + typeInterpolations.put("$Type$", dataClazzName); + if (userTasks != null) { CompilationUnit userTaskClazz = templateBuilder.build(context, REST_USER_TASK_TEMPLATE_NAME) @@ -210,10 +228,21 @@ public String generate() { ClassOrInterfaceDeclaration userTaskTemplate = userTaskClazz .findFirst(ClassOrInterfaceDeclaration.class) .orElseThrow(() -> new NoSuchElementException("Compilation unit doesn't contain a class or interface declaration!")); + + taskModelFactoryUnit = parse(this.getClass().getResourceAsStream("/class-templates/TaskModelFactoryTemplate.java")); + String taskModelFactorySimpleClassName = ucFirst(ProcessToExecModelGenerator.extractProcessId(processId) + "_" + "TaskModelFactory"); + taskModelFactoryUnit.setPackageDeclaration(process.getPackageName()); + taskModelFactoryClassName = process.getPackageName() + "." + taskModelFactorySimpleClassName; + ClassOrInterfaceDeclaration taskModelFactoryClass = taskModelFactoryUnit.findFirst(ClassOrInterfaceDeclaration.class).orElseThrow(IllegalStateException::new); + taskModelFactoryClass.setName(taskModelFactorySimpleClassName); + MethodDeclaration taskModelFactoryMethod = taskModelFactoryClass + .findFirst(MethodDeclaration.class, m -> m.getNameAsString().equals("from")) + .orElseThrow(IllegalStateException::new); + SwitchStmt switchExpr = taskModelFactoryMethod.getBody().get().findFirst(SwitchStmt.class).get(); + for (UserTaskModelMetaData userTask : userTasks) { String methodSuffix = sanitizeName(userTask.getName()) + "_" + index.getAndIncrement(); userTaskTemplate.findAll(MethodDeclaration.class).forEach(md -> { - MethodDeclaration cloned = md.clone(); template.addMethod(cloned.getName() + "_" + methodSuffix, Keyword.PUBLIC) .setType(cloned.getType()) @@ -223,7 +252,7 @@ public String generate() { }); template.findAll(StringLiteralExpr.class).forEach(s -> interpolateUserTaskStrings(s, userTask)); - template.findAll(ClassOrInterfaceType.class).forEach(c -> interpolateUserTaskTypes(c, userTask.getInputModelClassSimpleName(), userTask.getOutputModelClassSimpleName())); + template.findAll(ClassOrInterfaceType.class).forEach(c -> interpolateUserTaskTypes(c, userTask)); template.findAll(NameExpr.class).forEach(c -> interpolateUserTaskNameExp(c, userTask)); if (!userTask.isAdHoc()) { template.findAll(MethodDeclaration.class) @@ -231,13 +260,15 @@ public String generate() { .filter(md -> md.getNameAsString().equals("signal_" + methodSuffix)) .collect(Collectors.toList()).forEach(template::remove); } + // 0 leave default clause at the end + switchExpr.getEntries().add(0, userTask.getModelSwitchEntry()); + } + typeInterpolations.put("$TaskModelFactory$", taskModelFactoryClassName); + } template.findAll(StringLiteralExpr.class).forEach(this::interpolateStrings); - Map typeInterpolations = new HashMap<>(); - typeInterpolations.put("$Clazz$", resourceClazzName); - typeInterpolations.put("$Type$", dataClazzName); template.findAll(ClassOrInterfaceType.class).forEach(cls -> interpolateTypes(cls, typeInterpolations)); template.findAll(MethodDeclaration.class).forEach(this::interpolateMethods); @@ -321,12 +352,7 @@ private void interpolateUserTaskStrings(StringLiteralExpr vv, UserTaskModelMetaD } private void interpolateUserTaskNameExp(NameExpr name, UserTaskModelMetaData userTask) { - String identifier = name.getNameAsString(); - - name.setName(identifier.replace("$TaskInput$", userTask.getInputModelClassSimpleName())); - - identifier = name.getNameAsString(); - name.setName(identifier.replace("$TaskOutput$", userTask.getOutputModelClassSimpleName())); + name.setName(userTask.templateReplacement(name.getNameAsString())); } private void interpolateMethods(MethodDeclaration m) { @@ -336,30 +362,23 @@ private void interpolateMethods(MethodDeclaration m) { m.setName(interpolated); } - private void interpolateUserTaskTypes(Type t, String inputClazzName, String outputClazzName) { + private void interpolateUserTaskTypes(Type t, UserTaskModelMetaData userTask) { if (t.isArrayType()) { t = t.asArrayType().getElementType(); } if (t.isClassOrInterfaceType()) { SimpleName returnType = t.asClassOrInterfaceType().getName(); - interpolateUserTaskTypes(returnType, inputClazzName, outputClazzName); - t.asClassOrInterfaceType().getTypeArguments().ifPresent(o -> interpolateUserTaskTypeArguments(o, - inputClazzName, - outputClazzName)); + interpolateUserTaskTypes(returnType, userTask); + t.asClassOrInterfaceType().getTypeArguments().ifPresent(o -> interpolateUserTaskTypeArguments(o, userTask)); } } - private void interpolateUserTaskTypes(SimpleName returnType, String inputClazzName, String outputClazzName) { - String identifier = returnType.getIdentifier(); - - returnType.setIdentifier(identifier.replace("$TaskInput$", inputClazzName)); - - identifier = returnType.getIdentifier(); - returnType.setIdentifier(identifier.replace("$TaskOutput$", outputClazzName)); + private void interpolateUserTaskTypes(SimpleName returnType, UserTaskModelMetaData userTask) { + returnType.setIdentifier(userTask.templateReplacement(returnType.getIdentifier())); } - private void interpolateUserTaskTypeArguments(NodeList ta, String inputClazzName, String outputClazzName) { - ta.stream().forEach(t -> interpolateUserTaskTypes(t, inputClazzName, outputClazzName)); + private void interpolateUserTaskTypeArguments(NodeList ta, UserTaskModelMetaData userTask) { + ta.stream().forEach(t -> interpolateUserTaskTypes(t, userTask)); } private String sanitizeName(String name) { @@ -373,4 +392,8 @@ public String generatedFilePath() { protected boolean isPublic() { return KogitoWorkflowProcess.PUBLIC_VISIBILITY.equalsIgnoreCase(process.getVisibility()); } + + public boolean hasUserTask() { + return userTasks != null; + } } diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceQuarkusTemplate.java b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceQuarkusTemplate.java index 3e1494aa587..82adff1666c 100644 --- a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceQuarkusTemplate.java +++ b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceQuarkusTemplate.java @@ -54,6 +54,7 @@ import org.kie.kogito.process.workitem.AttachmentInfo; import org.kie.kogito.process.workitem.Comment; import org.kie.kogito.process.workitem.Policies; +import org.kie.kogito.process.workitem.TaskModel; import org.kie.kogito.process.impl.Sig; import org.kie.kogito.services.uow.UnitOfWorkExecutor; import org.kie.kogito.auth.IdentityProvider; @@ -106,7 +107,7 @@ public class $Type$Resource { return process.instances() .findById(id, ProcessInstanceReadMode.READ_ONLY) .map(pi -> pi.variables().toOutput()) - .orElseThrow(() -> new NotFoundException()); + .orElseThrow(NotFoundException::new); } @DELETE @@ -122,7 +123,7 @@ public class $Type$Resource { pi.abort(); return pi.checkError().variables().toOutput(); })) - .orElseThrow(() -> new NotFoundException()); + .orElseThrow(NotFoundException::new); } @PUT @@ -136,19 +137,23 @@ public class $Type$Resource { .instances() .findById(id) .map(pi -> pi.updateVariables(resource).toOutput())) - .orElseThrow(() -> new NotFoundException()); + .orElseThrow(NotFoundException::new); } @GET @Path("/{id}/tasks") @Produces(MediaType.APPLICATION_JSON) - public List getTasks_$name$(@PathParam("id") String id, + public List getTasks_$name$(@PathParam("id") String id, @QueryParam("user") final String user, @QueryParam("group") final List groups) { return process.instances() .findById(id, ProcessInstanceReadMode.READ_ONLY) - .map(pi -> pi.workItems(Policies.of(user, groups))) - .orElseThrow(() -> new NotFoundException()); + .map(pi -> pi + .workItems(Policies.of(user, groups)) + .stream() + .map($TaskModelFactory$::from) + .collect(Collectors.toList())) + .orElseThrow(NotFoundException::new); } } diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceSpringTemplate.java b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceSpringTemplate.java index 7b95e78147a..cef2c6abf06 100644 --- a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceSpringTemplate.java +++ b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceSpringTemplate.java @@ -35,6 +35,7 @@ import org.kie.kogito.process.workitem.AttachmentInfo; import org.kie.kogito.process.workitem.Comment; import org.kie.kogito.process.workitem.Policies; +import org.kie.kogito.process.workitem.TaskModel; import org.kie.kogito.services.uow.UnitOfWorkExecutor; import org.jbpm.process.instance.impl.humantask.HumanTaskHelper; import org.jbpm.process.instance.impl.humantask.HumanTaskTransition; @@ -134,13 +135,18 @@ public class $Type$Resource { } @GetMapping(value = "/{id}/tasks", produces = MediaType.APPLICATION_JSON_VALUE) - public ResponseEntity> getTasks_$name$(@PathVariable("id") String id, + public ResponseEntity> getTasks_$name$(@PathVariable("id") String id, @RequestParam(value = "user", required = false) final String user, @RequestParam(value = "group", required = false) final List groups) { return process.instances() .findById(id, ProcessInstanceReadMode.READ_ONLY) - .map(pi -> pi.workItems(Policies.of(user, groups))) + .map(pi -> pi + .workItems(Policies.of(user, groups)) + .stream() + .map($TaskModelFactory$::from) + .collect(Collectors.toList())) .map(m -> ResponseEntity.ok(m)) .orElseGet(() -> ResponseEntity.notFound().build()); + } } diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceUserTaskQuarkusTemplate.java b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceUserTaskQuarkusTemplate.java index 0eca453ec7d..705c3e2213e 100644 --- a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceUserTaskQuarkusTemplate.java +++ b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceUserTaskQuarkusTemplate.java @@ -55,7 +55,7 @@ public Response signal(@PathParam("id") final String id, @Context UriInfo uriInf } return Response.status(Response.Status.NOT_FOUND).build(); }); - }).orElseThrow(() -> new NotFoundException()); + }).orElseThrow(NotFoundException::new); } @POST @@ -81,7 +81,7 @@ public Response signal(@PathParam("id") final String id, @Context UriInfo uriInf HumanTaskTransition.withModel(phase, model, Policies.of(user, groups))); return pi.variables().toOutput(); })) - .orElseThrow(() -> new NotFoundException()); + .orElseThrow(NotFoundException::new); } @@ -103,7 +103,7 @@ public Response signal(@PathParam("id") final String id, @Context UriInfo uriInf taskId, wi -> HumanTaskHelper.updateContent(wi, model), Policies.of(user,groups))))) - .orElseThrow(() -> new NotFoundException()); + .orElseThrow(NotFoundException::new); } @@ -130,7 +130,7 @@ public Response signal(@PathParam("id") final String id, @Context UriInfo uriInf HumanTaskTransition.withModel(phase, model, Policies.of(user, groups))); return pi.variables().toOutput(); })) - .orElseThrow(() -> new NotFoundException()); + .orElseThrow(NotFoundException::new); } @@ -138,14 +138,14 @@ public Response signal(@PathParam("id") final String id, @Context UriInfo uriInf @GET @Path("/{id}/$taskName$/{taskId}") @Produces(MediaType.APPLICATION_JSON) - public $TaskInput$ getTask(@PathParam("id") String id, + public $TaskModel$ getTask(@PathParam("id") String id, @PathParam("taskId") String taskId, @QueryParam("user") final String user, @QueryParam("group") final List groups) { return process.instances() .findById(id, ProcessInstanceReadMode.READ_ONLY) - .map(pi -> $TaskInput$.from(pi.workItem(taskId, Policies.of(user, groups)))) - .orElseThrow(() -> new NotFoundException()); + .map(pi -> $TaskModel$.from(pi.workItem(taskId, Policies.of(user, groups)))) + .orElseThrow(NotFoundException::new); } @GET @@ -190,7 +190,7 @@ public Map getSchemaAndPhases(@PathParam("id") final String id, Policies.of(user, groups))); return pi.variables().toOutput(); })) - .orElseThrow(() -> new NotFoundException()); + .orElseThrow(NotFoundException::new); } @POST @@ -218,7 +218,7 @@ public Response addComment(@PathParam("id") final String id, .toString()) .build()).entity(comment).build(); }) - .orElseThrow(() -> new NotFoundException())); + .orElseThrow(NotFoundException::new)); } @PUT @@ -241,7 +241,7 @@ public Comment updateComment(@PathParam("id") final String id, taskId, wi -> HumanTaskHelper.updateComment(wi, commentId, comment, user), Policies.of(user, groups))) - .orElseThrow(() -> new NotFoundException())); + .orElseThrow(NotFoundException::new)); } @DELETE @@ -264,7 +264,7 @@ public Response deleteComment(@PathParam("id") final String id, Policies.of(user, groups)); return (removed ? Response.ok() : Response.status(Status.NOT_FOUND)).build(); }) - .orElseThrow(() -> new NotFoundException())); + .orElseThrow(NotFoundException::new)); } @POST @@ -292,7 +292,7 @@ public Response addAttachment(@PathParam("id") final String id, .toString()) .build()).entity(attachment).build(); }) - .orElseThrow(() -> new NotFoundException())); + .orElseThrow(NotFoundException::new)); } @PUT @@ -315,7 +315,7 @@ public Attachment updateAttachment(@PathParam("id") final String id, taskId, wi -> HumanTaskHelper.updateAttachment(wi, attachmentId, attachment, user), Policies.of(user, groups))) - .orElseThrow(() -> new NotFoundException())); + .orElseThrow(NotFoundException::new)); } @DELETE @@ -338,7 +338,7 @@ public Response deleteAttachment(@PathParam("id") final String id, Policies.of(user, groups)); return (removed ? Response.ok() : Response.status(Status.NOT_FOUND)).build(); }) - .orElseThrow(() -> new NotFoundException())); + .orElseThrow(NotFoundException::new)); } @GET @@ -350,7 +350,7 @@ public Attachment getAttachment(@PathParam("id") final String id, @QueryParam("user") final String user, @QueryParam("group") final List groups) { Attachment attachment = HumanTaskHelper.findTask(process.instances().findById(id).orElseThrow( - () -> new NotFoundException()), taskId, Policies.of(user, groups)) + NotFoundException::new), taskId, Policies.of(user, groups)) .getAttachments().get(attachmentId); if (attachment == null) { throw new NotFoundException("Attachment " + attachmentId + " not found"); @@ -365,7 +365,7 @@ public Collection getAttachments(@PathParam("id") final String id, @PathParam("taskId") final String taskId, @QueryParam("user") final String user, @QueryParam("group") final List groups) { - return HumanTaskHelper.findTask(process.instances().findById(id).orElseThrow(() -> new NotFoundException()), + return HumanTaskHelper.findTask(process.instances().findById(id).orElseThrow(NotFoundException::new), taskId, Policies.of(user, groups)) .getAttachments().values(); } @@ -379,7 +379,7 @@ public Comment getComment(@PathParam("id") final String id, @QueryParam("user") final String user, @QueryParam("group") final List groups) { Comment comment = HumanTaskHelper.findTask(process.instances().findById(id).orElseThrow( - () -> new NotFoundException()), taskId, Policies.of(user, groups)) + NotFoundException::new), taskId, Policies.of(user, groups)) .getComments().get(commentId); if (comment == null) { throw new NotFoundException("Comment " + commentId + " not found"); @@ -394,7 +394,7 @@ public Collection getComments(@PathParam("id") final String id, @PathParam("taskId") final String taskId, @QueryParam("user") final String user, @QueryParam("group") final List groups) { - return HumanTaskHelper.findTask(process.instances().findById(id).orElseThrow(() -> new NotFoundException()), + return HumanTaskHelper.findTask(process.instances().findById(id).orElseThrow(NotFoundException::new), taskId, Policies.of(user, groups)) .getComments().values(); } diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceUserTaskSpringTemplate.java b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceUserTaskSpringTemplate.java index 2d89bd1e178..f47d27a403c 100644 --- a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceUserTaskSpringTemplate.java +++ b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/RestResourceUserTaskSpringTemplate.java @@ -345,7 +345,7 @@ public ResponseEntity> getComments(@PathVariable("id") final } @GetMapping(value = "/{id}/$taskName$/{taskId}", produces = MediaType.APPLICATION_JSON_VALUE) - public ResponseEntity<$TaskInput$> getTask(@PathVariable("id") String id, + public ResponseEntity<$TaskModel$> getTask(@PathVariable("id") String id, @PathVariable("taskId") String taskId, @RequestParam(value = "user", required = false) final String user, @RequestParam(value = "group", @@ -353,7 +353,7 @@ public ResponseEntity> getComments(@PathVariable("id") final return process .instances() .findById(id) - .map(pi -> $TaskInput$.from(pi.workItem(taskId, Policies.of(user, groups)))) + .map(pi -> $TaskModel$.from(pi.workItem(taskId, Policies.of(user, groups)))) .map(m -> ResponseEntity.ok(m)) .orElseGet(() -> ResponseEntity.notFound().build()); } diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/TaskModelFactoryTemplate.java b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/TaskModelFactoryTemplate.java new file mode 100644 index 00000000000..5e5d9cbd36d --- /dev/null +++ b/kogito-codegen-modules/kogito-codegen-processes/src/main/resources/class-templates/TaskModelFactoryTemplate.java @@ -0,0 +1,30 @@ +/* + * Copyright 2019 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jbpm.process.codegen; + +import org.kie.kogito.process.workitem.TaskModel; + +public class $TaskModelFactory$ { + + public static TaskModel from(org.kie.kogito.process.WorkItem workItem) { + TaskModel taskModel; + switch (workItem.getName()) { + default: + throw new IllegalArgumentException("Invalid task name for work item "+workItem); + } + return taskModel; + } +} \ No newline at end of file