Interface IElementHandler<TData,​TElement extends IWorkflowElementEntity>

    • Field Detail

      • CURRENT_HANDLER_VERSION

        static final String CURRENT_HANDLER_VERSION
        The version string of the current formcycle application, as returned by default by getVersion(). Does not include suffixes etc., only major, minor, and patch.
    • Method Detail

      • extractDescription

        default String extractDescription​(TData data)
        Retrieves the name that will be stored as AWorkflowElement.getDescription(). For example, actions may let the user enter a description for the action, which would be returned by this method. A condition node may an explanation of the test condition as the description.

        The default implementation checks whether the getDataModelClass() implements IDescriptionProviding and if it does, returns IDescriptionProviding.getDescription(). Otherwise returns an empty string.

        Parameters:
        data - The data of the workflow element for which to retrieve the description.
        Returns:
        The description of the workflow element with the given data.
      • extractName

        default String extractName​(TData data)
        Retrieves the name that will be stored as AWorkflowElement.getName(). For example, actions may let the user enter the name of the action, which would be returned by this method. A condition node may use a summary of the test condition as the name. A button trigger event may use the name of the button.

        The default implementation checks whether the getDataModelClass() implements INameProviding and if it does, returns INameProviding.getName().

        Parameters:
        data - The data of the workflow element for which to retrieve the name.
        Returns:
        The name of the workflow element with the given data.
      • getCascadingStyleSheet

        @Deprecated
        default IResourceDescriptor getCascadingStyleSheet​(boolean devMode)
                                                    throws URISyntaxException,
                                                           MalformedURLException
        Deprecated.
        Retrieves the CSS resources required by elements of this kind, when this node is displayed in the workflow designer. The CSS is added globally to the document - make sure to use unique class names. We recommend you keep to the conventions as laid out by BEM.
        Parameters:
        devMode - true if the application is started in development mode. May be used to deliver uncompressed files with a inline source maps for development.
        Returns:
        The resource descriptor for the required CSS files. When no CSS resource is required, you may return either EmptyResourceDescriptor.INSTANCE or null.
        Throws:
        URISyntaxException - This exception is declared for convenience. Usually you want to create a new URI from a fixed path that is known to exist. In case this exception is thrown, the resource will not be loaded and an appropriate error is shown to the user.
        MalformedURLException - This exception is declared for convenience. You may want to create an URI from a fixed URL. In case this exception is thrown, the resource will not be loaded and an appropriate error is shown to the user.
      • getCascadingStyleSheet

        default IResourceDescriptor getCascadingStyleSheet​(Locale locale,
                                                           boolean devMode)
                                                    throws URISyntaxException,
                                                           MalformedURLException
        Retrieves the CSS resources required by elements of this kind, when this node is displayed in the workflow designer. The CSS is added globally to the document - make sure to use unique class names. We recommend you keep to the conventions as laid out by BEM.
        Parameters:
        locale - The current language of the workflow designer. You can use this parameter to include localized message in the script.
        devMode - true if the application is started in development mode. May be used to deliver uncompressed files with a inline source maps for development.
        Returns:
        The resource descriptor for the required CSS files. When no CSS resource is required, you may return either EmptyResourceDescriptor.INSTANCE or null.
        Throws:
        URISyntaxException - This exception is declared for convenience. Usually you want to create a new URI from a fixed path that is known to exist. In case this exception is thrown, the resource will not be loaded and an appropriate error is shown to the user.
        MalformedURLException - This exception is declared for convenience. You may want to create an URI from a fixed URL. In case this exception is thrown, the resource will not be loaded and an appropriate error is shown to the user.
      • getDataModelClass

        Class<? extends TData> getDataModelClass()
        Returns the class of the custom properties used by the elements handled by this element logic handler.

        The custom properties of a workflow element are internally stored as JSON. To ease the development work, you can specify a model class, and the JSON is automatically converted to an instance of that model class. Please note that the model class must be compatible with serialization mechanism used by JSON.

        See getVersion() for how custom properties are updated.

        If you need more control over serialization and deserialization, specify JSONObject as the type parameter and return JSONObject.class. You will then receive the raw JSON data and may perform the serialization in whatever way you like.

        Returns:
        The class corresponding to the type parameter TData.
      • getDisplayLabel

        default String getDisplayLabel​(IGetDisplayLabelParams<TData> params)
        Retrieves the display label for a workflow element. Compared with extractName(Object), this label may depend on the locale and is not saved in the database. Furthermore, the display label may depend on the context, such as the name of a workflow state etc. While not every element may have a name, every element should have a display label.

        The default implementation delegates to extractName(Object).

        Parameters:
        params - Parameters with the element's deserialized properties model, the locale and additional context data.
        Returns:
        The display label of the element in the given locale.
      • getElementSummaryModel

        default Serializable getElementSummaryModel​(IGetElementSummaryParams<TData> params)
                                             throws Exception
        When the user clicks on the info icon of a node or trigger, an panel with a quick summary of that node or trigger opens. By default, this panel only shows the available values returned by the node and which errors it can throw. You can implement getElementSummaryXhtml() to include a custom summary of the element's current properties. If you do, you should also override this method. It must create the view model for the XHTML page. The value returned by this method is passed to the XHTML page via the expression language variable model.

        If you wish to display a quick summary as a list of key value pairs derived directly from the properties model, consider using the mixin IKeyValueSummarizableElement.

        Parameters:
        params - The current properties model of the node or trigger.
        Returns:
        The view model for the summary. When null, no summary is displayed.
        Throws:
        Exception - When anything goes wrong. This is caught and logged, and no summary gets displayed.
      • getElementSummaryXhtml

        default URL getElementSummaryXhtml()
                                    throws MalformedURLException
        When the user clicks on the info icon of a node or trigger, an panel with a quick summary of that node or trigger opens. By default, this panel only shows the available values returned by the node and which errors it can throw. You can implement this method to include a custom summary of the element's current properties. If you do, you should also override getElementSummaryModel(IGetElementSummaryParams).

        This method should return the path to the XHTML page for the custom workflow element summary that is shown in an overlay when the user click on the info icon on a node or trigger. Usually the XHTML file is part of the JAR resources of the module or plugin. In this case, you should return an URL to a JAR file resource (jar:file:/...) like so:

         @Override
         public URL getXhtmlView() {
           return getClass().getResource("/path/to/view.xhtml");
         }
         

        The XHTML page should be a passive view without any interaction. The following to variables are made available to the XHTML page:

        Returns:
        The XHTML page for the custom element summary. When null, no summary is displayed.
        Throws:
        MalformedURLException - When the URL could not be created. When this exception is thrown, it is treated as if null had been returned.
      • getFastJsonConverter

        default IFastJsonConverter getFastJsonConverter()
        Finds the converter that is used to convert between the properties model (getDataModelClass()) and its JSON representation. The default implementation uses a JSON converter without any special custom serializers or configuration and should be sufficient for most cases. Please note you can influence how objects are serialized and deserialized via annotations, such as JSONField, which should be sufficient in most cases.

        The default implementation returns a JSON converter that can convert most basic Java types; and makes use of the class loader of that loaded the class of this handler implementation.

        The converter returned by this method must not be thread-safe, the system must guarantee it is not shared between threads.

        Returns:
        The JSON converter to use for converting between the properties model and its JSON representation.
      • getFilterCriteriaForEntities

        default de.xima.cmn.criteria.FilterCriterion getFilterCriteriaForEntities​(IGetFilterCriteriaForEntitiesParams params)
        Similar to readEntityReferences(IReadEntityRefsParams), but on a database level. Called when the system needs to search for referencing entities, but without reading all elements from the database first.

        A filter for the standard entity reference search terms is added automatically. When extractSearchTerms(IExtractSearchTermsParams) is not overridden or returns the standard ISearchTermHandler.entitySearchTerms(IEntityReference), then you do not have to implement this method. This method is provided for non-standard cases when you need to add a custom filter.

        When this method returns null, no special separate filter for elements of this type is added. When this returns a non-null value, a separate filter for elements of this type that also match the returned filter is added to the database query. The filter criterion returned by this method is used for a query for AWorkflowElement entities, i.e. all attribute names in filter criteria must be relative to that entity.

        To illustrate what the default filter that is added automatically looks like, assume an inbox is given. Then, to limit the result to elements which have a search term with the default entity reference key set to the UUID of the inbox, use:

         if (params.getEntity() instanceof Postfach.class) {
           return params.searchTermExists(params.entitySearchTerm(Postfach.class), params.entitySearchTerm(params.getEntity()));
         }
         return null;
         
        To add a custom filter that matches elements which have a key customKey set to a custom value, use:
         return params.searchTermExists("customKey", "customValue");
         
        To create a complex filter, use or / and etc.

        Basic restrictions such as the element type, the form record and project are applied automatically by the system and do not need to be included in the returned filter.

        Parameters:
        params - Params with the entity for which to scan for references.
        Returns:
        A filter criterion to restrict the list of matching element for this handler type. When null is returned, no special filters for this element type are added.
        Throws:
        RuntimeException - Should not throw under normal circumstances. Any exception throws by this method is caught and logged; and treated as if null had been returned.
      • getHelpPageLocation

        default IElementHelpLocation getHelpPageLocation​(Locale locale)
                                                  throws IOException
        Parameters:
        locale - Locale for which the help page was requested.
        Returns:
        The location of the help page for this element. This is used to show a help link to the user with more details on how they can use the workflow element.
        Throws:
        IOException - Provided for convenience when you wish to create new URLs or read files from the classpath. When this method throws an exception, it is treated as if this method had returned null, e.g. no help page will be shown.
      • getJavaScript

        @Deprecated
        default IResourceDescriptor getJavaScript​(boolean devMode)
                                           throws URISyntaxException,
                                                  MalformedURLException
        Deprecated.
        Retrieves the JavaScript resources required by elements of this kind.

        The JavaScript code is loaded automatically by the flowchart and executed in a local function scope. The variable Flowchart is made available in that scope and contains the public client-side API of the flowchart. The JavaScript must (synchronously!) register the appropriate element handler either via a call to

         Flowchart.registerNode(nodeType: string, nodeHandler: Object): void;
         Flowchart.registerTrigger(triggerType: string, triggerHandler: Object): void;
         
        See the TypeScript declaration file shipped in the NPM module fc-workflow-flowchart for an exact description of the node and trigger handler object. It also contains all available methods exposed on the Flowchart object. We recommend you build your plugin against the declaration file to prevent errors when updating the formcycle version (removed or deprecated methods etc.)
        Parameters:
        devMode - true if the application is started in development mode. May be used to deliver uncompressed files with a inline source maps for development.
        Returns:
        The resource descriptor for the required JavaScript files. When no CSS resource is required, you may return either EmptyResourceDescriptor.INSTANCE or null.
        Throws:
        URISyntaxException - This exception is declared for convenience. Usually you want to create a new URI from a fixed path that is known to exist. In case this exception is thrown, the resource will not be loaded and an appropriate error is shown to the user.
        MalformedURLException - This exception is declared for convenience. You may want to create an URI from a fixed URL. In case this exception is thrown, the resource will not be loaded and an appropriate error is shown to the user.
      • getJavaScript

        default IResourceDescriptor getJavaScript​(Locale locale,
                                                  boolean devMode)
                                           throws URISyntaxException,
                                                  MalformedURLException
        Retrieves the JavaScript resources required by elements of this kind.

        The JavaScript code is loaded automatically by the flowchart and executed in a local function scope. The variable Flowchart is made available in that scope and contains the public client-side API of the flowchart. The JavaScript must (synchronously!) register the appropriate element handler either via a call to

         Flowchart.registerNode(nodeType: string, nodeHandler: Object): void;
         Flowchart.registerTrigger(triggerType: string, triggerHandler: Object): void;
         
        See the TypeScript declaration file shipped in the NPM module fc-workflow-flowchart for an exact description of the node and trigger handler object. It also contains all available methods exposed on the Flowchart object. We recommend you build your plugin against the declaration file to prevent errors when updating the formcycle version (removed or deprecated methods etc.)
        Parameters:
        locale - The current language of the workflow designer. You can use this parameter to include localized message in the script.
        devMode - true if the application is started in development mode. May be used to deliver uncompressed files with a inline source maps for development.
        Returns:
        The resource descriptor for the required JavaScript files. When no CSS resource is required, you may return either EmptyResourceDescriptor.INSTANCE or null.
        Throws:
        URISyntaxException - This exception is declared for convenience. Usually you want to create a new URI from a fixed path that is known to exist. In case this exception is thrown, the resource will not be loaded and an appropriate error is shown to the user.
        MalformedURLException - This exception is declared for convenience. You may want to create an URI from a fixed URL. In case this exception is thrown, the resource will not be loaded and an appropriate error is shown to the user.
      • getLocalizedTypeName

        String getLocalizedTypeName​(Locale locale)
        Parameters:
        locale - Locale for which the type name should be returned.
        Returns:
        A human-readable name of this element type in the given locale.
      • getPropertiesBeanClass

        default Class<? extends IElementPropertiesBean<TData,​TElement>> getPropertiesBeanClass()
        Returns the class of the bean that should be used when editing the properties of a workflow element. May be null if you do not require any bean or custom logic. When you only wish to access the properties of your getDataModelClass(), you do have to use a custom bean - the model is available via the expression language variable model. See getPropertiesViewXhtml() for further details.

        The default returns null, which uses no extra bean. An extra bean may not be required for simple UIs if you only need to access the properties model of the workflow element - see getPropertiesViewXhtml().

        Returns:
        The class of the bean to use for editing a workflow node's properties.
        See Also:
        getPropertiesViewXhtml()
      • getPropertiesViewXhtml

        URL getPropertiesViewXhtml()
                            throws MalformedURLException
        This method must return the path to the XHTML page for the custom user interface. Usually the XHTML file is part of the JAR resources of the module or plugin. In this case, you should return an URL to a JAR file resource (jar:file:/...) like so:
         @Override
         public URL getXhtmlView() {
           return getClass().getResource("/path/to/view.xhtml");
         }
         

        The contents of this XHTML page is included in the properties panel, without a fieldset or container around it, but already inside a form (i.e. do not use a h:form as that would result in an error). You should wrap your custom UI in a naming container to ensure unique IDs that do not clash with other plugins or actions. The following is a recommended template on which you may base your UI:

         <ui:composition xmlns="http://www.w3.org/1999/xhtml"
           xmlns:h="http://xmlns.jcp.org/jsf/html"
           xmlns:f="http://xmlns.jcp.org/jsf/core"
           xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
           xmlns:o="http://omnifaces.org/ui" xmlns:p="http://primefaces.org/ui"
           xmlns:xi="http://www.xima.de/taglib/xfc">
        
           <!-- Enable bean validation (when #validateLocal is implemented via the bean validator)-->
           <o:validateBean value="#{model}" showMessageFor="@violating"  method="validateActual" />
        
           <xi:namingContainer id="myAwesomeWorkflowElement">
        
             <!--Base info with name and description (when TData extends BaseActionProps) -->
             <xi:newWorkflowActionBase id="base" value="#{model}" legend="#{msg['wf.node.myawesomelememnt']}" />
        
             <!-- Remove when TData does not have a ISingleFileProviding field -->
             <xi:singleFile id="resource" value="#{model.singleFile}" required="true" />
        
             <!-- Remove when TData does not have a IMultiFileProviding field -->
             <xi:multiFile id="resource" value="#{model.multiFile}" required="true" />
        
             <!-- Remove when TData does not implement IProviding -->
             <xi:fileProvision id="providing" value="#{model.fileProvision}" />
        
             <!-- Custom section with editors specific to your workflow element -->
             <p:fieldset legend="#{msg['MyAwesomeWorkflowElementProps.fieldset.base']}" styleClass="fc-fieldset">
        
               <!-- A simple input field bound to the mail property of your properties model -->
               <xi:inputText id="mail" label="#{msg['MyAwesomeWorkflowElementProps.mail']}" formPlaceholder="true"
                 value="#{model.mail}" forceIndicateRequired="true" >
                 <p:ajax event="change" partialSubmit="true"
                   listener="#{elementPropertiesBean.storeCurrent}" process="@this"
                   update=":flowchartForm:flowchart" global="false" />
               </xi:inputText>
        
            </p:fieldset>
        
           </xi:namingContainer>
         </ui:composition>
         

        The XHTML page may access the following expression language variables:

        • model: The deserialized custom properties of the workflow element, of the type TData.
        • provider: An object that implements IWorkflowProvider, for accessing various data, such as a list of all users or text templates.
        • msg: The localized messages as returned by getResourceBundle(Locale). Empty when that method returns null. For example, if the resource bundle contains the key mail.label, you can access the localized message via the EL expression ['mail.label']

        To access the values of an enum or the constants defined by a class, consider using

         <xi:importConstants type="my.fully.classified.path.MyEnum" var="MyEnum" loader="#{model}"/>
         
        The loader argument is only required for plugins and ensures that the correct class loader is used that knows about the plugin class. Without the loader attribute, the above is equivalent to the PrimeFaces tag handler <p:importConstants />.
        Returns:
        Path to the XHTML view. If the action can be configured, this must not return null. If you do return null, it will be treated as an error and an appropriate message is displayed to the user informing them that the properties panel could not be loaded. If the action cannot be configured (i.e. when the action is not selectable), this should return null.
        Throws:
        MalformedURLException - This exception is declared for convenience - normally you would use new URL(String) with a constant URL string that should not throw. In case an exception is thrown, it is treated the same as if this returned null.
      • getResourceBundle

        default ResourceBundle getResourceBundle​(Locale locale)
        Retrieves the resource bundle that should be used, for example, for custom validation messages generated during validation. If you use IWorkflowBeanValidator for validation, the bean validator will use this bundle by default.

        When this resource bundle has no messages for a certain key, or when this returns null, the default resource bundles of formcycle are used as a fallback. This also means you do not have to include validation messages for common validation constraints such as NotEmpty (but you can if you wish to override the defaults).

        Specified by:
        getResourceBundle in interface IResourceBundleLocator
        Parameters:
        locale - A locale, for which a resource bundle shall be retrieved. Must not be null.
        Returns:
        The resource bundle to use for localized messages.
      • getVersion

        default String getVersion()
        Finds the current version of this element handler. The properties of the workflow element are stored as JSON, and this version is stored along with it. Later (such as after the software was updated), this JSON needs to be retrieved again, the version is compared against the current version. When the versions are not equal, ICustomParametersUpdateable.updateCustomParams(IUpdateCustomParametersParams) is called on the raw JSON data, giving you a chance to update the properties before they are deserialized.

        By default, this returns the current version of formcycle. For plugins, it is strongly recommended that you use the version of the plugin.

        Returns:
        The current version of this workflow element handler.
        See Also:
        ICustomParametersUpdateable
      • isAvailable

        default boolean isAvailable​(IIsAvailableParams<TData> params)
        Checks whether this workflow element is available to the given client. If this return false, this action cannot be used in the workflow designer. When attempting to execute a workflow with an unavailable action, an error of type NODE_UNAVAILABLE is thrown. The default implementation always returns true.
        Parameters:
        params - The node's data, the entity context, and the current client.
        Returns:
        Whether the workflow element is available to the given client.
      • isHasUserVisibleName

        default boolean isHasUserVisibleName()
        Checks whether this workflow element has a user-facing extractName(Object). If so, the name should usually be editable on the UI. If not, the name is a technical name that should not be shown to the user.
        Returns:
        true if the extractName(Object) can be visible to the user.
      • readEntityReferences

        default Iterable<IEntityReferenceDescriptor> readEntityReferences​(IReadEntityRefsParams<TData> params)
        Extracts all entity references from the given properties model. These entity references are used are required, for example, when exporting a form or importing a form into the system. Entities in the export file need to be checked against existing entities, and possibly need to be updated.

        The default implementation scans for all entity references via reflection. This assumes that (a) you are not using JSONObject as the data model class; and (b) that you always use UuidEntityRef in your properties model. Nested properties and entity references within Lists and Maps are supported.

        When you override this method, you should also implement the corresponding updateEntityReferences method.

        Parameters:
        params - Query to get the entity references for
        Returns:
        All IEntityReferenceDescriptor contained in the given model. null is treated as if no descriptors had been returned.
      • readPlaceholders

        default Iterable<IPlaceholderProperty<?,​?>> readPlaceholders​(IReadPlaceholdersParams<TData> params)
        Finds and returns all placeholders that are contained in the given properties model. The descriptors returned by this method may (but are not always) later be passed to writePlaceholders(IWritePlaceholdersParams).

        The default implementation scans via reflection for the standard formcycle placeholder pattern in all fields of type string. When the properties model is a JSONObject, all strings inside that JSON object are scanned.

        Parameters:
        params - Parameters with an element's properties model from which to read the placeholders.
        Returns:
        All placeholders that are contained in the properties model. No guarantees are required regarding the order in which the placeholders are returned. null is treated as if no placeholders had been returned.
        See Also:
        writePlaceholders(IWritePlaceholdersParams)
      • validateLocal

        IWorkflowElementValidationResult validateLocal​(IElementLocalValidationParams<TData,​TElement> params)
                                                throws WorkflowValidationException
        Performs a local validation of the given workflow workflow element properties. This method should only validate the properties of the given workflow element, without respect to any other workflow elements.

        This method allows you to implement custom validation logic. Consider using IBeanValidatingElement and annotating your properties model class with the annotation from the bean annotation API javax.validation. This also offers the advantage that it can be integrated into JSF, allowing you to use the same validations for the UI view as well.

        Parameters:
        params - The properties to validate. Also provides access to the project, client etc.
        Returns:
        The result of the validation, i.e. whether the workflow element is valid, and a list of messages to display to the user. If this returns, this is treated as if a valid result without messages had been returned. You may use use params.getValidationContext().resultBuilder() to create the result, or implement the interface yourself. To indicate that the validation was performed, but no validation constraints were violated, simply call build on the result builder and return that, without adding any messages.
        Throws:
        WorkflowValidationException - When the validation could not be performed. Please note that this is meant for unexpected errors only - you should not throw an exception if a workflow element is simply just invalid.
      • writeEntityReferences

        default int writeEntityReferences​(IWriteEntityRefsParams<TData> params)
        Writes all given entity references back to the given properties model. This method is the complement to readEntityReferences(IReadEntityRefsParams). The references passed to this method use the same key as returned by readEntityReferences(IReadEntityRefsParams).

        The default implementation writes the entity references via reflection. This assumes that (a) you are not using JSONObject as the data model class; and (b) that you always use UuidEntityRef in your properties model. Nested properties and entity references within Lists and Maps are supported.

        When you override this method, you should also implement the corresponding readEntityReferences.

        Parameters:
        params - The current properties model and the updated references that should be set on the properties model.
        Returns:
        The number of references were set.
      • writePlaceholders

        default void writePlaceholders​(IWritePlaceholdersParams<TData> params)
        Writes all placeholders to the given properties model. The data that is passed to this method is the data that was previously returned by readPlaceholders(IReadPlaceholdersParams). Implementors may assume that the properties model was not changed between the call to readPlaceholders(IReadPlaceholdersParams) and this method call.

        The default implementation scans via reflection for the standard formcycle placeholder pattern in all fields of type string. When the properties model is a JSONObject, all strings inside that JSON object are scanned.

        Parameters:
        params - Parameters with the properties model and the placeholders that should be written to that properties model.