Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Triquetrum/CapeCode

< Triquetrum
Revision as of 18:36, 31 January 2017 by Erwindl0.gmail.com (Talk | contribs) (Loading palette contributions via OSGi services)

CapeCode

This intro to be corrected/extended by Christoper or someone else with real knowledge on CapeCode.

CapeCode is a project of the UC Berkeley CHESS group, who are also the originators of Ptolemy II. CapeCode is related to the domain of IoT, implementing assemblies of accessors to interact with connected devices in a well-defined way, reusing formal concepts from Ptolemy II's actor system.

Supporting CapeCode actors in Triquetrum's editor

As in other cases where we want to extend Triquetrum with extra actors, adding CapeCode actors consists of 2 main actions :

  • providing the actor implementations in a way that is accessible by the editor and execution runtime
  • defining editor palette contributions for them

The CapeCode actors that we consider here are JSAccessor actors, whose concrete behaviour is implemented in JavaScript. Adding CapeCode actors in a Triquetrum installation then requires at least the following :

  • having the JSAccessor implementation (+dependencies) in the Triquetrum platform and being able to locate and load the JavaScript files that define the actor implementations. This is tricky business, especially when we want to remain compatible with native (non-OSGi) Ptolemy II approaches to load files from its class path.
  • being able to read actor library definitions from CapeCode hosts and files and to add them to the editor palette. Ideally this should work without needing to restart the editor for each change in the CapeCode configuration.

In the text below we'll describe an approach to support CapeCode contributions to the editor palette.

Loading palette contributions dynamically

The traditional approach to define the graphical editor's palette is via extensions in the plugin.xml files of one or more palette configuration bundles.

This fits well with standard Eclipse practices but has some disadvantages as well, such as :

  • Palette contents must be known & defined upfront,
  • by someone able to develop Eclipse plugins,
  • that must be built and then installed in the (RCP) application,
  • which even requires a restart to activate the changes/additions.

But this approach does not fit the requirements for CapeCode where actor library configurations are managed in JSON files, hosted on remote locations. We don't want to replicate such configurations in plugin.xml files, nor having to go through complete development/build/install cycles to add or maintain CapeCode libraries.

So an alternative mechanism to add palette contributions has been put in place, to have the possibility to reuse CapeCode's existing library definition files. It is based on a provider interface (in org.eclipse.triquetrum.workflow.editor.palette.spi):

 public interface PaletteEntryProvider {
   /**
    *
    * @return the palette entries from this provider, as configuration elements
    */
   IConfigurationElement[] getPaletteEntries();
 }

org.eclipse.triquetrum.workflow.editor.palette.spi.PaletteConfigurationElement is a plain implementation of IConfigurationElement that provides all properties of palette entries to match the features that are also supported in the extension point schema.

To load an accessor library, the provider interface can be implemented based on CapeCode's org.terraswarm.accessor.AccessorLibrary. An example AccessorPaletteEntryProvider implementation can be found on https://github.com/erwindl0/triquetrum-capecode.

The implementation constructs an AccessorLibrary instance from the library json definition :

 CompositeEntity ce = new CompositeEntity();
 ce.setName("CapeCode configuration");
 AccessorLibrary accessorLibrary = new AccessorLibrary(ce, "Accessors");
 accessorLibrary.configure(null, URI.createPlatformPluginURI("org.eclipse.triquetrum.ptolemy.capecode.palette",true).toString() + "/src/main/resources", null);
 accessorLibrary.populate();

The library reads the JSON file from a URI and creates accessors for each entry in there. The test file contains one simple accessor :

 [
   "BaseA.js"
 ]

Each library entry then gets transformed in an IConfigurationElement as follows :

 public IConfigurationElement[] getPaletteEntries() {
   try {
     AccessorLibrary accessorLibrary = buildAccessorLibrary();
     List<IConfigurationElement> results = new ArrayList<>();
     for (Entity<?> accessor : (List<Entity<?>>) accessorLibrary.entityList()) {
       Map<String, String> attributes = new HashMap<>();
       attributes.put(CLASS, accessor.getClass().getName()); // (1)
       attributes.put(DISPLAY_NAME, accessor.getDisplayName()); // (2)
       attributes.put(ICON, "icons/time_obj.gif"); // (3)
       attributes.put(TYPE, "Actor"); // (4)
       PaletteConfigurationElement pce = new PaletteConfigurationElement("entry", "org.eclipse.triquetrum.ptolemy.capecode.palette", attributes );
       results.add(pce);
     }
     return results.toArray(new IConfigurationElement[0]);
   } catch (IllegalActionException | NameDuplicationException | MalformedURLException e) {
     LOGGER.error("Error obtaining palette entries for Acessors library", e);
     return new IConfigurationElement[] {};
   }
 }

Following properties are set (constants from static imports):

  1. CLASS : the java class name of the accessor, always JSAccessor
  2. DISPLAY_NAME : the name to be displayed in the palette
  3. ICON : this is not supported as such in the accessor library json files it seems.
  4. TYPE : always Actor

The provider implementation can then be registered in an extension, i.o. needing to statically define each individual entry in there :

 <plugin>
  <extension
        point="org.eclipse.triquetrum.workflow.editor.paletteContribution">
     <group
           displayName="CapeCode"
           provider="org.eclipse.triquetrum.ptolemy.capecode.palette.AccessorPaletteEntryProvider">
     </group>
  </extension>
 </plugin>

And the results is something like :

CapeCodePaletteProvider.jpg

Hacks

The whole thing is still just a proof of concept! A fully functional implementation is not possible until the incompatibilities are resolved for loading the JavaScript files, between Ptolemy II's native approach and an OSGi runtime's requirements. To get the editor loading an accessor, all kinds of dirty hacks were done...

  • Mocked the setup in a local json file.
  • Ptolemy sources for jjs were extracted in the osgi-2.0 branch in the accessors project and adapted to get the files loading upto the point needed to get the editor working.
  • All dependencies (netty, vert.x, jackson, org.terraswarm.accessor, ...) were added by hand in the dvp workspace. Details can be communicated/improved on request.

Back to the top