diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..c76c8b6 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,14 @@ +// If one would like to add/remove/modify user preferences without modifying the content of the +// workspace settings file, then one would need to modify the `settings.json` under here: +// - Windows: %APPDATA%\Code\User\settings.json +// - Linux: $HOME/.config/Code/User/settings.json +// - Mac: $HOME/Library/Application Support/Code/User/settings.json +{ + // Organize Java Imports + "editor.codeActionsOnSave": { + "source.organizeImports": "explicit" + }, + // Checkstile + "java.checkstyle.configuration": "https://raw.githubusercontent.com/imixs/imixs-workflow/master/imixs-checkstyle-8.44.xml", + "editor.formatOnSave": true +} \ No newline at end of file diff --git a/pom.xml b/pom.xml index 9596db3..15644c0 100644 --- a/pom.xml +++ b/pom.xml @@ -55,7 +55,7 @@ UTF-8 - 6.0.6 + 6.1.0-SNAPSHOT 6.0 src/main/webapp war @@ -436,12 +436,16 @@ + + org.imixs.workflow + imixs-workflow-core + ${org.imixs.workflow.version} + org.imixs.workflow imixs-workflow-engine ${org.imixs.workflow.version} - org.imixs.workflow imixs-workflow-jax-rs diff --git a/src/main/java/org/imixs/application/model/ModelController.java b/src/main/java/org/imixs/application/model/ModelController.java index efd1325..2dced69 100644 --- a/src/main/java/org/imixs/application/model/ModelController.java +++ b/src/main/java/org/imixs/application/model/ModelController.java @@ -27,39 +27,40 @@ package org.imixs.application.model; +import java.io.ByteArrayInputStream; import java.io.IOException; +import java.io.InputStream; import java.io.Serializable; import java.text.ParseException; import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.List; -import java.util.Map; import java.util.Set; +import java.util.logging.Level; import java.util.logging.Logger; -import jakarta.ejb.EJB; -import jakarta.enterprise.context.RequestScoped; -import jakarta.faces.event.ActionEvent; -import jakarta.inject.Inject; -import jakarta.inject.Named; -import java.util.logging.Level; import javax.xml.parsers.ParserConfigurationException; import org.imixs.workflow.FileData; import org.imixs.workflow.ItemCollection; -import org.imixs.workflow.Model; -import org.imixs.workflow.bpmn.BPMNModel; -import org.imixs.workflow.bpmn.BPMNParser; +import org.imixs.workflow.bpmn.BPMNUtil; import org.imixs.workflow.engine.ModelService; -import org.imixs.workflow.engine.SetupService; import org.imixs.workflow.engine.WorkflowService; import org.imixs.workflow.exceptions.AccessDeniedException; import org.imixs.workflow.exceptions.ModelException; -import org.imixs.workflow.exceptions.PluginException; +import org.imixs.workflow.faces.data.WorkflowController; +import org.openbpmn.bpmn.BPMNModel; +import org.openbpmn.bpmn.exceptions.BPMNModelException; +import org.openbpmn.bpmn.util.BPMNModelFactory; import org.xml.sax.SAXException; +import jakarta.ejb.EJB; +import jakarta.enterprise.context.RequestScoped; +import jakarta.faces.event.ActionEvent; +import jakarta.inject.Inject; +import jakarta.inject.Named; + /** * The ModelController provides informations about workflow models. * @@ -82,38 +83,37 @@ public class ModelController implements Serializable { @Inject protected ModelUploadHandler modelUploadHandler; + @Inject + WorkflowController workflowController; + @EJB protected ModelService modelService; @EJB protected WorkflowService workflowService; - @EJB - protected SetupService setupService; - - private final Map modelEntityCache = new HashMap<>(); - private static final Logger logger = Logger.getLogger(ModelController.class.getName()); - /** * returns all groups for a version * * @param version * @return */ - public List getGroups(String version) { + public Set getGroups(String version) { try { - return modelService.getModel(version).getGroups(); + BPMNModel model; + model = modelService.getModelManager().getModel(version); + return modelService.getModelManager().findAllGroups(model); } catch (ModelException e) { logger.log(Level.WARNING, "Unable to load groups:{0}", e.getMessage()); } // return empty result - return new ArrayList<>(); + return new LinkedHashSet<>(); } /** - * Returns a String list of all WorkflowGroup names. + * Returns a sorted list of all WorkflowGroups from all models. * * Workflow groups of the system model will be skipped. * @@ -126,26 +126,24 @@ public List getGroups(String version) { */ public List getWorkflowGroups() { - Set set = new HashSet<>(); - List versions = modelService.getVersions(); - for (String version : versions) { - try { - if (version.startsWith("system-")) - continue; - set.addAll(modelService.getModel(version).getGroups()); - } catch (ModelException e) { - logger.log(Level.SEVERE, "Unable to find model version:{0}", e.getMessage()); - } - } + // Set set = new HashSet<>(); + // List versions = modelService.getModelManager().getVersions(); List result = new ArrayList<>(); - // add all groups without '~' - for (String agroup : set) { - if (result.contains(agroup)) - continue; - if (agroup.contains("~")) + for (BPMNModel model : modelService.getModelManager().getAllModels()) { + String version = BPMNUtil.getVersion(model); + // Skip system model.. + if (version.startsWith("system-")) { continue; - result.add(agroup); + } + Set groups = modelService.getModelManager().findAllGroups(model); + for (String groupName : groups) { + if (result.contains(groupName)) + continue; + if (groupName.contains("~")) + continue; + result.add(groupName); + } } Collections.sort(result); @@ -154,101 +152,81 @@ public List getWorkflowGroups() { } /** - * Returns a String list of all Sub-WorkflowGroup names for a specified - * WorkflowGroup. - * - * - * A SubWorkflowGroup contains a '~' in its name. - * - * The SubWorflowGroup list is used to assign sub workflow Group to a workitem + * Finds the first matching model version for a group name * - * @see getWorkflowGroups() - * - * @param parentWorkflowGroup - * - the parent workflow group name - * @return list of all sub workflow groups for the given parent group name + * @param group + * @return + * @throws ModelException */ - public List getSubWorkflowGroups(String parentWorkflowGroup) { + public String findVersionByGroup(String group) throws ModelException { + return modelService.getModelManager().findVersionByGroup(group); + } - Set set = new HashSet<>(); - List versions = modelService.getVersions(); - for (String version : versions) { - try { - if (version.startsWith("system-")) - continue; - set.addAll(modelService.getModel(version).getGroups()); - } catch (ModelException e) { - logger.log(Level.SEVERE, "Unable to find model version:{0}", e.getMessage()); + /** + * Loads the first start task in the corresponding workflow group + * + * @param group + * @return + * @throws ModelException + */ + public ItemCollection findStartTaskByGroup(String version, String group) throws ModelException { + ItemCollection result = null; + BPMNModel model = modelService.getModelManager().getModel(version); + List startTasks; + try { + startTasks = modelService.getModelManager().findStartTasks(model, group); + if (startTasks.size() > 0) { + result = startTasks.get(0); } + } catch (BPMNModelException e) { + throw new ModelException(ModelException.INVALID_MODEL, + "Unable to create new workitem by group '" + group + "'", e); } - List result = new ArrayList<>(); - - // add all groups starting with GROUP~ - for (String agroup : set) { - if (result.contains(agroup)) - continue; - if (!agroup.startsWith(parentWorkflowGroup + "~")) - continue; - result.add(agroup); + if (result == null) { + logger.warning("No Model found for Group '" + group + "'"); } - Collections.sort(result); return result; } /** - * Returns a model object for corresponding workitem. + * Creates a new process instance based on a given start task in the + * corresponding workflow model + * group * - * @param workitem - * @return + * @param version - model version + * @param startTask - initial task + * @return new process instance + * @throws ModelException */ - public Model getModelByWorkitem(ItemCollection workitem) { - try { - return modelService.getModelByWorkitem(workitem); - } catch (ModelException e) { - return null; + public ItemCollection startWorkflowByTask(String version, ItemCollection startTask) throws ModelException { + ItemCollection result = null; + workflowController.create(version, startTask.getItemValueInteger("numprocessid"), null); + if (result == null) { + logger.warning("No Model found for model version '" + version + "'"); } + return result; + } /** - * Returns a model object for corresponding workflow group. + * returns all model versions. Used by the Model View * - * @param group * @return */ - public Model getModelByGroup(String group) { - List versions = modelService.findVersionsByGroup(group); - if (!versions.isEmpty()) { - String version = versions.get(0); - try { - return modelService.getModel(version); - } catch (ModelException e) { - logger.warning(e.getMessage()); - return null; - } - } - return null; + public List getVersions() { + return modelService.getModelManager().getVersions(); } /** - * returns all model versions + * Returns a Model Entity. Used by the Model View * + * @param version * @return */ - public List getVersions() { - return modelService.getVersions(); - } - public ItemCollection getModelEntity(String version) { - - ItemCollection result = modelEntityCache.get(version); - if (result == null) { - result = modelService.loadModelEntity(version); - modelEntityCache.put(version, result); - } - - return result; + return modelService.loadModel(version); } /** @@ -265,30 +243,31 @@ public ItemCollection getModelEntity(String version) { * */ public void doUploadModel(ActionEvent event) - throws ModelException, ParseException, ParserConfigurationException, SAXException, IOException { + throws ModelException { List fileList = modelUploadHandler.getModelUploads().getFileData(); if (fileList == null) { return; } for (FileData file : fileList) { - logger.log(Level.INFO, "Import bpmn-model: {0}", file.getName()); // test if bpmn model? if (file.getName().endsWith(".bpmn")) { - BPMNModel model = BPMNParser.parseModel(file.getContent(), "UTF-8"); - modelService.saveModel(model); - continue; - } + InputStream inputStream = new ByteArrayInputStream(file.getContent()); + BPMNModel model; + try { + model = BPMNModelFactory.read(inputStream); - if (file.getName().endsWith(".ixm")) { - setupService.importXmlEntityData(file.getContent()); - continue; + modelService.saveModel(model); + continue; + } catch (BPMNModelException e) { + throw new ModelException(ModelException.INVALID_MODEL, + "Unable to read model file: " + file.getName(), e); + } + } else { + // model type not supported! + logger.log(Level.WARNING, "Invalid Model Type. Model {0} can't be imported!", file.getName()); } - - // model type not supported! - logger.warning("Invalid Model Type. Model can't be imported!"); - } modelUploadHandler.reset(); } @@ -297,7 +276,7 @@ public void doUploadModel(ActionEvent event) * This Method deletes the given model from the database and the internal model * cache. * - * @param modelversion + * @param modelversion * @throws AccessDeniedException * @throws ModelException */ @@ -305,55 +284,4 @@ public void deleteModel(String modelversion) throws AccessDeniedException, Model modelService.deleteModel(modelversion); } - /** - * This method returns a process entity for a given ModelVersion or null if no - * entity exists. - * - * - * @param modelversion - * - version for the model to search the process entity - * @param processid - * - id of the process entity - * @return an instance of the matching process entity - */ - public ItemCollection getProcessEntity(int processid, String modelversion) { - try { - return modelService.getModel(modelversion).getTask(processid); - } catch (ModelException e) { - logger.log(Level.WARNING, "Unable to load task {0} in model version ''{1}'' - {2}", new Object[]{processid, modelversion, e.getMessage()}); - } - return null; - } - - /** - * This method return the 'rtfdescription' of a processentity and applies the - * dynamic Text replacement function from the jee plugin - * - * @param processid - * @param modelversion - * @param documentContext - * @return - */ - public String getProcessDescription(int processid, String modelversion, ItemCollection documentContext) { - ItemCollection pe = null; - try { - pe = modelService.getModel(modelversion).getTask(processid); - } catch (ModelException e1) { - logger.log(Level.WARNING, "Unable to load task {0} in model version ''{1}'' - {2}", new Object[]{processid, modelversion, e1.getMessage()}); - - } - if (pe == null) { - return ""; - } - String desc = pe.getItemValueString("rtfdescription"); - - try { - desc = workflowService.adaptText(desc, documentContext); - } catch (PluginException e) { - logger.log(Level.WARNING, "Unable to update processDescription: {0}", e.getMessage()); - } - - return desc; - - } } diff --git a/src/main/java/org/imixs/application/plugin/CommentPlugin.java b/src/main/java/org/imixs/application/plugin/CommentPlugin.java index fbee6cc..a0d5343 100644 --- a/src/main/java/org/imixs/application/plugin/CommentPlugin.java +++ b/src/main/java/org/imixs/application/plugin/CommentPlugin.java @@ -65,17 +65,17 @@ public class CommentPlugin extends AbstractPlugin { * This method updates the comment list. There for the method copies the * txtComment into the txtCommentList and clears the txtComment field * - * @param adocumentContext - * @param documentActivity + * @param workitem + * @param event * @throws org.imixs.workflow.exceptions.PluginException */ @SuppressWarnings("unchecked") @Override - public ItemCollection run(ItemCollection adocumentContext, ItemCollection documentActivity) throws PluginException { + public ItemCollection run(ItemCollection workitem, ItemCollection event) throws PluginException { - documentContext = adocumentContext; + documentContext = workitem; - ItemCollection evalItemCollection = this.getWorkflowService().evalWorkflowResult(documentActivity, "item", adocumentContext); + ItemCollection evalItemCollection = this.getWorkflowService().evalWorkflowResult(event, "item", workitem); // test if comment is defined in model if (evalItemCollection != null) { diff --git a/src/main/java/org/imixs/application/plugin/DemoPlugin.java b/src/main/java/org/imixs/application/plugin/DemoPlugin.java index cbdb256..30ba477 100644 --- a/src/main/java/org/imixs/application/plugin/DemoPlugin.java +++ b/src/main/java/org/imixs/application/plugin/DemoPlugin.java @@ -69,7 +69,7 @@ public ItemCollection run(ItemCollection adocumentContext, ItemCollection adocum logger.info("...running demo plugin..."); // test model service - List versions = modelService.getVersions(); + List versions = modelService.getModelManager().getVersions(); for (String aversion : versions) { logger.log(Level.INFO, "ModelVersion found: {0}", aversion); } diff --git a/src/main/java/org/imixs/application/ui/form/CustomFormController.java b/src/main/java/org/imixs/application/ui/form/CustomFormController.java index 6e76826..c2226c9 100644 --- a/src/main/java/org/imixs/application/ui/form/CustomFormController.java +++ b/src/main/java/org/imixs/application/ui/form/CustomFormController.java @@ -34,19 +34,14 @@ import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; +import java.util.logging.Level; import java.util.logging.Logger; -import jakarta.ejb.EJB; -import jakarta.enterprise.context.ConversationScoped; -import jakarta.enterprise.event.Observes; -import jakarta.inject.Named; -import java.util.logging.Level; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.imixs.workflow.ItemCollection; -import org.imixs.workflow.Model; import org.imixs.workflow.engine.ModelService; import org.imixs.workflow.exceptions.AccessDeniedException; import org.imixs.workflow.exceptions.ModelException; @@ -57,6 +52,11 @@ import org.w3c.dom.NodeList; import org.xml.sax.SAXException; +import jakarta.ejb.EJB; +import jakarta.enterprise.context.ConversationScoped; +import jakarta.enterprise.event.Observes; +import jakarta.inject.Named; + /** * The CustomFormController computes a set of fields based on a data object * provided by the model. @@ -170,11 +170,9 @@ public void computeFieldDefinition(ItemCollection workitem) { */ @SuppressWarnings("unchecked") private String fetchFormDefinitionFromModel(ItemCollection workitem) { - Model model; ItemCollection task; try { - model = modelService.getModelByWorkitem(workitem); - task = model.getTask(workitem.getTaskID()); + task = modelService.getModelManager().loadTask(workitem); } catch (ModelException e) { logger.log(Level.WARNING, "unable to parse data object in model: {0}", e.getMessage()); return ""; diff --git a/src/main/webapp/pages/workflow/start.xhtml b/src/main/webapp/pages/workflow/start.xhtml index 7631748..55b0d5d 100644 --- a/src/main/webapp/pages/workflow/start.xhtml +++ b/src/main/webapp/pages/workflow/start.xhtml @@ -1,9 +1,6 @@ - @@ -30,26 +27,26 @@
    - - - -
  • + + +
  • + -

    -

    - +

    + +

    + + -
  • + + +
@@ -58,4 +55,4 @@ -
+ \ No newline at end of file