5 Replies Latest reply on Oct 17, 2005 8:32 AM by koen.aers

    Jbpm designer and context menu extensibility

    krzogr

      Hi,

      I am working on a product which uses internally Jbpm designer plugin and adds additional functionality on top of it. I was thinking about extending context (popup) menus in the workflow designer and I thought it would be good to discuss it with you. I think that the following requirements regarding context menus can be specified from my point of view:

      1. It would be good if I could extend (define) context menus without needing to change original JBPM designer code. Currently it is rather impossible:
      - menu in the source page is set to null (cvs head)
      - context menu in the diagram page requires changes in designer code.

      2. It would be good if I could define the context menus declaratively (plugin xml and extension points).
      I have checked that even using the declarative approach I can specify that particular item should be displayed only when a certain graph element (e.g. task node) is selected.

      3. Sometimes it may be required that I want to alter the menu structure dynamically (using IMenuListener). IMHO if I want to add to the context menu the standard actions (e.g. Cut) the best way is to use the dynamic approach.

      4. It shouldn't be a problem if default context menus already contain sensible elements (e.g. in the the source page "cut", "copy", ect.). But all items which don't make sense shouldn?t be visible by default (e.g. 'Run' in the source page).
      In the worst case I could deal with the unwanted menu options using eclipse activities (I have checked it and it works). The only requirement is that all actions in the menu must be properly contributed (defninitionId must be specified).

      What do you think about these issues?

      Here is my suggestion about the implementation. It basically consists of additional classes and methods which would be added to the original designer code:

      1. Declarative extension mechanism: each page in the designer editor (or at least 'diagram' and 'source') would create the context menu (may be empty) and register it for extensions. Each menu would use a different registration name (identifier) so that adding elements to these menus can be controlled.

      package org.jbpm.ui.editor;
      
      public class DesignerEditor
      {
      ?
       private void initSourcePage()
       {
       int pageCount = getPageCount();
       for (int i = 0; i < pageCount; i++)
       {
       if (getEditor(i) instanceof StructuredTextEditorXML) {
       sourcePage = (StructuredTextEditorXML)getEditor(i);
       processDefinition = getProcessDefinition(sourcePage);
       }
       }
       if (sourcePage != null)
       {
       initSourcePageContextMenu(sourcePage.getTextViewer().getTextWidget());
       }
       }
      
       private void initSourcePageContextMenu(final Control control)
       {
       sourceContextMenuManager = new MenuManager("#PopupMenu");
       sourceContextMenuManager.setRemoveAllWhenShown(true);
       sourceContextMenuManager.addMenuListener(new IMenuListener(){
       public void menuAboutToShow(IMenuManager m)
       {
       fillContextMenu(m);
       }
       });
       Menu menu = sourceContextMenuManager.createContextMenu(control);
       getSite().registerContextMenu("org.jbpm.ui.editor.DesignerEditor.SourcePopupMenu", sourceContextMenuManager, getSite().getSelectionProvider());
      
       control.setMenu(menu);
       }
      
       private void fillContextMenu(final IMenuManager menuManager) {
      
       menuManager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
       }
      }


      Similar code in org.jbpm.ui.editor.DesignerModelViewer and maybe in other pages (swimlane, design?).

      2. Dynamic extension mechanism: menu listeners:

      package org.jbpm.ui.editor;
      
      /**
       * Identifies individual page in the Jbpm editor window.
       */
      public enum DesignerEditorPageId
      {
       DIAGRAM,
       SWIMLANE,
       DESIGN,
       SOURCE,
      }
      
      package org.jbpm.ui.editor;
      
      public class DesignerEditor
      {
      ?
       public final void addContextMenuListener(final DesignerEditorPageId pageId, final IMenuListener listener)
       {
       switch(pageId)
       {
       case DIAGRAM:
       graphPage.getDesignerModelViewer().addContextMenuListener(listener);
       break;
       case SWIMLANE:
       throw new UnsupportedOperationException("Not implemented");
       case DESIGN:
       throw new UnsupportedOperationException("Not implemented");
       case SOURCE:
       sourceContextMenuManager.addMenuListener(listener);
       break;
       default:
       throw new RuntimeException("Unknown page id: " + pageId);
       }
       }
      
       public final void removeContextMenuListener(final DesignerEditorPageId pageId, final IMenuListener listener)
       {
       switch(pageId)
       {
       case DIAGRAM:
       graphPage.getDesignerModelViewer().removeContextMenuListener(listener);
       break;
       case SWIMLANE:
       throw new UnsupportedOperationException("Not implemented");
       case DESIGN:
       throw new UnsupportedOperationException("Not implemented");
       case SOURCE:
       sourceContextMenuManager.removeMenuListener(listener);
       break;
       default:
       throw new RuntimeException("Unknown page id: " + pageId);
       }
       }
      
       /**
       * Additional utility method.
       */
       public final IEditorPart getEditorPage(final DesignerEditorPageId pageId)
       {
       switch(pageId)
       {
       case DIAGRAM:
       return getEditor(0);
       case SWIMLANE:
       return getEditor(1);
       case DESIGN:
       return getEditor(2);
       case SOURCE:
       return getEditor(3);
       default:
       throw new RuntimeException("Unknown page id: " + pageId);
       }
       }
      }


      What do you think of such changes? Is it possible to have some of the features described above implemented in standard workflow designer plugin?

      Kind regards,

      Krzysztof



        • 1. Re: Jbpm designer and context menu extensibility
          koen.aers

          Krzysztof,

          Thanks for the post.
          First of all, I completely agree with your point of view. I experimented already with adding a context menu to the graphical viewer, but the nasty 'Run' and other entries bothered me so I removed it again. It looks like your solution makes a lot of sense.
          So if I understand correctly, you would suppress most of the entries using the Eclipse activity mechanism, that I did not know before and that I would like you to detail a bit. In addition, you would create all context menus dynamically using the appropriate objectcontributions to the popupmenu extension point? If this works out correctly I think that would be really great. Does anyone else on this forum have an opinion or additional ideas about this?

          Regards,
          Koen

          • 2. Re: Jbpm designer and context menu extensibility
            krzogr

            Hi Koen,

            Regarding the activity mechanism:

            I am using this mechanism to hide the unwanted contributions in my RCP application. It seems to work but there were some problems. First of all in order for this mechanism to work all contributed actions needs to be properly defined (definitionId should be specified). Using the activity mechanism I was able to hide nearly all unwanted contributions from the default source popup menu (when it was not set to null). Unfortunately there were few contributions made by one of the base classes which didn't specify the action definitionId. In that case even the activity mechanism didn't help and these contributions were visible in the popup menu. See e.g. org.eclipse.wst.sse.ui.internal.properties.ShowPropertiesAction. This action doesn't specify the definition id and I was not able to hide it from the popup menu (it was contributed by one of the base classes).

            All the activity settings are controlled declarativly through plugin.xml. Here is the configuration from my application:

            <extension point="org.eclipse.ui.activities">
             <category
             name="Disabled category"
             id="com.axxia.wd.disabledCategory">
             </category>
             <activity
             name="Disabled activity"
             id="com.axxia.wd.disabledActivity">
             </activity>
             <categoryActivityBinding
             activityId="com.axxia.wd.disabledActivity"
             categoryId="com.axxia.wd.disabledCategory">
             </categoryActivityBinding>
             <activityPatternBinding
             activityId="com.axxia.wd.disabledActivity"
             pattern="org.eclipse.*/*">
             </activityPatternBinding>
             </extension>
            
             <extension point="org.eclipse.ui.activities">
             <category
             name="Enabled workflow category"
             id="com.axxia.wd.enabledCategory">
             </category>
             <activity
             name="Enabled workflow activity"
             id="com.axxia.wd.enabledActivity">
             </activity>
             <categoryActivityBinding
             activityId="com.axxia.wd.enabledActivity"
             categoryId="com.axxia.wd.enabledCategory">
             </categoryActivityBinding>
             <activityPatternBinding
             activityId="com.axxia.wd.enabledActivity"
             pattern="org.eclipse.ui.texteditor.save">
             </activityPatternBinding>
             <activityPatternBinding
             activityId="com.axxia.wd.enabledActivity"
             pattern="org.eclipse.ui.file.*">
             </activityPatternBinding>
             <activityPatternBinding
             activityId="com.axxia.wd.enabledActivity"
             pattern="org.eclipse.ui.edit.(cut|copy|paste|delete|undo|redo)">
             </activityPatternBinding>
             <activityPatternBinding
             activityId="com.axxia.wd.enabledActivity"
             pattern="org.eclipse.ui.help.*">
             </activityPatternBinding>
             <activityPatternBinding
             activityId="com.axxia.wd.enabledActivity"
             pattern="org.eclipse.ui.views.*">
             </activityPatternBinding>
             <defaultEnablement id="com.axxia.wd.enabledActivity"/>
             </extension>


            The first entry tries to disable everything in the eclipse. The second specifies what should be enabled (I am using these actions). If I didn't enable them than even if I explicitly added them to the popup menu they wouldn't be visible.

            The last line (
            <defaultEnablement id="com.axxia.wd.enabledActivity"/>
            ) explicitly enables the activity when the application starts.

            Hope this helps. Let me know if you have any questions. I am still new to all these concepts so maybe some of these things can be done better/quicker?

            Kind regards,

            Krzysztof



            • 3. Re: Jbpm designer and context menu extensibility
              koen.aers

              Hi Krzysztof,

              I am back in jBPM land again, though I will be busy at JBoss World in Barcelona this week. Did you already try this piece of plugin.xml in the designer? Also, what happens when you have two plugins specifying conflicting activities?Anyways, I will try this for myself whenever I have time this week. If it works, I can check in your contributions.
              Regarding the actions without a definitionId, I would suggest you to file a bug report in the WTP bugzilla to provide such a definitionId (as it is a WTP issue). If you provide me the bug number, I will be happy to vote for it.

              Thanks and regards,
              Koen

              • 4. Re: Jbpm designer and context menu extensibility
                krzogr

                Hi Koen,

                Sorry for replying so late but I was very busy last week. I will try to file the bug regarding to WTP and let you know.

                Regarding activities: Yes I have tried activities in my code (Designer) and it seems to work (with the exceptions which I described). I am not sure if you should define anything related to activities in your plugin. See the following excerpts from Eclipse FAQ book:

                How do I add activities to my plug-in?
                You don?t. An important feature of activities is that they are not defined in the plug-ins alongside the functionality they describe
                [...]
                Typically activities will be defined by an administrator or product manager who is assembling an end-user application from a large pool of plug-ins. A power user who wants to coordinate a large set of plug-ins downloaded from the Web also may establish some activities.


                Kind regards,

                Krzysztof

                • 5. Re: Jbpm designer and context menu extensibility
                  koen.aers

                  Hi Krzysztof,

                  No worries, I have been very busy myself last two weeks. Okay, I get the activities thing now. but I did not yet try the code. I'll try as soon as I have time.

                  Cheers,
                  Koen