Selected Extension Points

The following sub-sections describe how to use selected extension points. The topics listed here do not cover all possible scenarios but are meant as a starting point for the most frequently needed extensions. If you have specific needs for modifying TopBraid EDG in your organization that are not covered here, please ask us and we may update this documentation.

The sections below include links to sample files for most extension points. You may put those samples into your TopBraid EDG Studio workspace where you can explore their implementation, try them out and even modify the samples.

Hint

Don’t just put all samples into your workspace at once. Each of the samples makes changes to the system, so you would see things like unexpected new menu items and background scripts that will be hard to understand without studying them individually.

Script-based Functions

This extension point can be used to install new SPARQL functions and JavaScript functions in the generated ADS APIs.

Samples:

TopBraid EDG Studio rendering the hello function

An example Script-based function in TopBraid EDG (Studio)

Instructions:

Instances of dash:ScriptFunction define functions that may be used from SPARQL or ADS scripts. Such functions encapsulate almost any business logic that can be expressed in JavaScript/ADS, as value of dash:js. The examples and the screenshot illustrate the mechanics.

Functions may take parameters, which must be declared using sh:parameter and can declare a return type using sh:returnType. All this is very similar to SHACL-SPARQL Functions from the SHACL Advanced Features specification. The main difference is that here we use dash:js to store the executable body of the function. That body needs to use the return keyword to specify the result value (if any).

There are two kinds of Script-based functions:

  • read-only functions have no value or false for dash:canWrite. These functions execute with a read-only API and are not permitted to make modifications or have side effects. These functions will be turned into SPARQL functions - all SPARQL functions are strictly read-only to avoid deadlocks and other SPARQL execution issues.

  • read/write functions have dash:canWrite true. These functions are only exposed through the ADS APIs and may make changes to the data and have other side effects.

Multi-Functions

This extension point can be used to install new ADS functions and SPARQL magic properties that return multiple rows of (potentially) multiple values each.

Samples:

See DASH Multi-Functions for technical background and further examples.

Note

Multi-functions should be stored in files ending with .api.ttl so that they are globally registered as SPARQL magic properties.

Constructors

This extension point can be used to override the Create New dialogs for instances of certain classes, for example to initialize new instances from values entered by the user.

Samples:

In this example the class Person has two properties (first name and last name). However, when a new instance is created, we want users to only enter the full name and then split that input string into the two name components. To do that, the class Person declares a dash:constructor:

A class definition with a constructor

Classes can define a Constructor

Here is how the constructor itself is defined:

The definition of a constructor

Constructors define input parameters and an ADS script to perform the actual construction

When the New button is pressed, the following dialog will appear:

Screenshot of a modified create dialog

The Create dialog only asks for the parameters defined in the constructor

The new instance is then derived from the entered parameter value:

Screenshot of an instance created using the constructor

The actual instance is created using the script of the constructor using the parameters as input

Note

Constructor scripts get the variable focusNode as input from the outside, pointing at the selected class. All other parameters are mapped to namesake variables based on the entered values, such as fullName here. The result value of the script (i.e. the last line) must be the newly created instance - this is needed to instruct the surrounding tool to highlight the new instance.

Hint

Constructors are using class inheritance. To keep things simple, there should only ever be one reachable constructor in the parent class hierarchy. Constructors of subclasses may however override the constructors of superclasses.

Change and Commit Scripts

This extension point can be used to install scripts that are triggered whenever a user makes changes to an asset collection, e.g. by pressing the Save Changes button on a form.

Samples:

These scripts can be split in two categories:

  • pre-commit scripts (dash:ChangeScript) are triggered anytime after a change is done in a graph, and executed within the edit itself. They may perform additional changes to the RDF graph and those changes will be bundled with the edit in the change history. In practice, this means that if there is some validation problem, the rule is triggered twice - once when the initial save button was clicked, and the second time when the save is confirmed. These rules are also executed in preview mode. Therefore, pre-commit rules (dash:ChangeScript) must not have other side effects such as sending out emails or updating external systems or graphs. Only the current default graph may be modified by them.

  • post-commit scripts (dash:CommitScript) are only executed once the edits to the data graph are persisted. Unlike their counterpart, these scripts are not triggered in preview mode, or if a constraint violation is blocking an edit. These scripts may have side-effects, meaning that updates to other graphs or sending notifications to external systems can be done.

Multiple scripts of the same category can be ordered using the sh:order, with the lower the value, the highest the execution priority.

In these scripts, the current changes from the active graph can be accessed via dataset.addedGraphURI for resource values that have been added and dataset.deletedGraphURI for resource values that have been deleted, in that particular edit. These graphs can be queried by using graph.withDataGraph(dataset.addedGraphURI, ...) or via SPARQL’s GRAPH keyword.

Resource Actions

This extension point can be used to install new items for the Explore and Modify menus of selected resources.

Samples:

More information on this extension point can be found at Resource Actions.

Batch Actions

This extension point can be used to install new items for the Batch Actions Menu. They are very similar to Resource Actions, except that the JavaScript code can access the array of selected nodes using the variable focusNodes.

Samples:

More information on this extension point can be found at Batch Actions.

Web Services

This extension point can be used to install new web services that can be called from the outside but execute within the TopBraid server.

Web services can be defined declaratively in ontologies or files as instances of certain classes. For example, ADS-based services may be instances of dash:GraphService and be stored in an Ontology asset collection or a file that is used by an Ontology. It is strongly recommended to use TopBraid EDG Studio to develop, test and harden your services before putting them into production.

As of TopBraid 7.2, there are several kinds of web services supported:

The RDF resources that declare these services must have a URI, and the URI is used to construct the URL under which the service can be called. The general pattern of web service URLs is:

/tbl/service/{graphId}/{servicePrefix}/{serviceLocalName}

As an example, we have a service that takes one parameter called name and is declared with the RDF resource exservice:HelloService. Assuming we want to call this service against the Geography taxonomy that is abbreviated geo, the URL becomes:

/tbl/service/geo/exservice/HelloService?name=World

The graphId part can be _ if no graph shall be pre-selected as query graph. This is called a context-free service call. Only services marked with dash:contextFree true can be called without a query graph. Such context-free services should be defined in .api.ttl files so that they are globally registered.

All web services need to declare a value for dash:apiStatus. The possible values are:

  • dash:Experimental for services that have just been introduced and may be used by early adopters

  • dash:Stable for services that have been well tested and which are expected to still exist in the next version(s)

  • dash:Deprecated for services that should no longer be used because they have become outdated or found problematic

You can deactivate most web services (except those based on SWP) by setting sh:deactivated true.

Hint

Go to Reports > Web Services Swagger UI to explore and possibly test the known web services. Administrators can go to Server Administration > TopBraid Platform Web Services to see all context-free web services.

Web Services based on ADS

Samples:

More information on this extension point can be found at ADS-based Web Services.

Web Services based on Functions

Samples:

Instructions:

All SHACL functions stored in .api.ttl files in the workspace that declare any value of dash:apiStatus can be called as web services against any (or none) target graph. Functions that are declared dash:canWrite true or sh:deactivated true will be excluded.

Services based on functions return nothing or a JSON object representing the RDF node produced by the function. For URI nodes and blank nodes the syntax is:

{
    uri: "http://example.org/ns#something"
}

For blank nodes the uri starts with _: followed by the internal identifier of the node. For literal nodes the syntax is:

{
    lex: "...",
    datatype: "URI of datatype",
    lang: "language tag if applicable",
}

The datatype field is not used for xsd:string literals, and lang is only used for rdf:langString literals.

See Script-based Functions.

Web Services based on Multi-Functions

Samples:

Instructions:

All instances of dash:MultiFunction stored in .api.ttl files in the workspace that declare any value of dash:apiStatus can be called as web services against any (or none) target graph. Multi-functions that are declared sh:deactivated true will be excluded.

Services based on multi-functions always return a JSON array with name-value pairs for each result variable, using the JSON syntax from Web Services based on Functions.

See Multi-Functions.

Web Services based on SWP

Samples:

Instructions:

SWP technology is used by TopBraid EDG to provide various kinds of functionality that is not available by other means. For example, the SWP element teamwork:createProject is a low-level module to create asset collections. If you need to access these features in web services then defining your own SWP-based services is sometimes the only option.

Warning

SWP services require a good understanding of TopBraid’s SWP technology. Unless you have been working with SWP for a long time, or you have been adviced by TopQuadrant staff, we suggest you try Web Services based on ADS first. See ADS and SWP on the role of SWP.

All SWP services need to be stored in .ui.ttl* files and are globally registered after a workspace refresh. You need to instantiate ui:Service, which is best done by subclassing ui:Services.

Use ui:prototype to write the body of the service. There is no reason to use dash:js here - use Web Services based on ADS instead if you would like to use JavaScript.

Hint

When you need to edit larger scripts you can switch the source code editor to full-screen mode by clicking on the label of prototype while the form is in view mode.

While all other web service types use SHACL vocabulary to declare the input parameters (using sh:parameter), SWP uses spl:Argument at spin:constraint. Services need to declare a value for dash:apiStatus.

You can deactivate existing SWP-based web services by setting ui:private true.

The result of these web services depends on the declared ui:responseType. When you subclass ui:JSONServices the response type will be inferred to be application/json, but you can potentially produce any kind of response based on the textual output of the SWP script.

Generators for the Problems and Suggestions Reports

This extension point can be used to have the Problems and Suggestions panel produce new kinds of results.

Samples:

Instructions:

Create an instance of tosh:ResultsGenerator in a .ui.ttlx file. In that instance, store the JavaScript code that shall be executed under dash:js. In that script, the variable resultsGraph.uri is the URI of the target graph that the script can add new results to. For example, use the script to generate new instances of dash:SuggestionResult, along with

  • one or more values for sh:resultMessage for human-readable messages

  • a value for sh:focusNode to link to the main resource that the result is about

  • a value for sh:resultSeverity (such as sh:Warning or sh:Info)

  • a value for sh:resultPath if the result is about a certain property path from the focus node

Finally, the result instance needs to be linked to the sh:ValidationReport instance using the pre-defined variable report using report.add(sh.result, result).

Note

See the SHACL Results Vocabulary for technical background on the results vocabulary.

See the DASH Suggestions Vocabulary for details on the suggestions framework.

Suggestion Generators

This extension point can be used to generate new Suggestions for the Problems and Suggestions panel and the Form panel.

Samples:

TopBraid EDG Studio with a suggested fix to a constraint violation

The suggestion generator in Action

Note

See the DASH Suggestions Vocabulary for background on the suggestions framework.

Instructions:

Instances of dash:ScriptSuggestionGenerator implement suggestion generators that are backed by an Active Data Shapes script. The script needs to return a JSON object or an array of JSON objects if it shall generate multiple suggestions. It may also return null to indicate that nothing was suggested.

Note that the whole script is evaluated as a (JavaScript) expression, and those will use the last value as result. So simply putting an object at the end of your script should do. Alternatively, define the bulk of the operation as a function and simply call that function in the script.

Each response object can have the following fields:

  • message: a human readable message, defaults to the rdfs:label(s) of the suggestion generator

  • add: an array of triples to add, each triple as an array with three nodes for subject, predicate and object

  • delete: like add, for the triples to delete

Suggestions with neither added nor deleted triples will be discarded.

At execution time, the script operates on the data graph as the active graph, with the following pre-bound variables:

  • focusNode: the NamedNode that is the sh:focusNode of the validation result

  • predicate: the NamedNode representing the predicate of the validation result, assuming sh:resultPath is a URI

  • value: the value node from the validation result’s sh:value, cast into the most suitable JavaScript object

  • the other pre-bound variables for the parameters of the constraint, e.g. in a sh:maxCount constraint it would be maxCount

The script will be executed in read-only mode, i.e. it cannot modify the graph.

Landing Page Gadgets

This extension point can be used to install new gadgets on the Home page of TopBraid EDG itself.

Samples:

Instructions:

In a .ui.ttlx file, make sure that teamwork.ui.ttlx is included so that you can create a subclass of teamwork:LandingPageGadgetHooks. In the dash:js of that subclass, use graph.html() in the last line to produce the HTML output that you would like to have inserted into the home page. Use the properties teamwork:landingPageColumn and teamwork:landingPageOrder as shown in the sample. Make sure the component has a suitable rdfs:label so that individual users can select to see or hide that gadget from their user-specific settings.

Login Form

To customize the EDG login form for Form Authentication:

1. Obtain the EDG webapp HTML templates

  • Find the file edg-webapp-XXX.jar, either in EDG Studio’s lib directory or in Tomcat’s webapps/edg/WEB-INF/lib directory

  • Copy the file to a convenient location, and rename the copy to have a .zip file extension

  • Unzip the file

  • Find the EDG webapp HTML templates in the unzipped directory META-INF/resources/login-form

2. Modify the templates

  • Modify the pages you wish to customize (typically, at least page-template.html)

  • If Javascript is required, take note of the Content Security Policy (CSP) restrictions

3. Test and deploy the customized files

With EDG Studio

  • Find Studio’s webapp directory. Typically this is server.8083/webapp inside the Studio directory, but could be different depending on the port that Studio is launched on

  • Create a subdirectory login-form inside webapp

  • Add any modified templates to this directory

  • Restart EDG Studio

With EDG Server

  • Inside Tomcat’s webapps/edg directory, create a subdirectory login-form

  • Add any modified templates to this directory

  • Restart Tomcat

Scheduled Jobs

This extension point can be used to define scripts that shall be executed in the background on a TopBraid EDG server, triggered in recurring intervals.

Samples:

Instructions:

In a .ui.ttlx file, make sure that teamwork.ui.ttlx is included so that you can create a subclass of scheduler:ScheduledJobs. In that subclass, define what should happen in your script under dash:js. Set scheduler:cronSchedule to something like 0 * * * * ? to have your script execute in regular intervals. You may need to edit this triple from the Source Code panel if you don’t see a widget on the form.

Hint

Use Administration > Scheduled Jobs to see if your scheduled job has been recognized, and to trigger it manually.

Custom Notifications

This extension point can be used to install new types of Notifications that can be triggered as side effects of various events in TopBraid EDG.

Samples:

Instructions:

In a .ui.ttlx file, make sure that teamwork.ui.ttlx is included so that you can create a subclass of one of the specific notification types. For example subclass teamwork:RegularEditNotification to add a notification after normal edits (on forms) have happened. Each notification needs to produce some text, ideally as an HTML snippet. Use dash:js to produce that text, e.g. using graph.html().

Then use the property arg:expression to specify under which condition the notification should be sent out. In the provided example, a notification is sent when a change has happened that involved the predicate skos:prefLabel. The syntax of those expressions is SPIN RDF notation, and the example is making a SPARQL function call. You could theoretically just set it to true to always send out notifications. Use the Source Code panel if you don’t see an input widget for arg:expression on the form.

Once you have defined your notification type and refreshed the workspace for the .ui.ttlx file to be recognized, you may need to activate the notification for some user roles in your asset collection.

Asset Collection Constructors

This extension point can be used to define web services that are also showing up as buttons on the New Button.

Samples:

The product has various examples as shown on the New Button. You can find their implementation as instances of dash:GraphConstructorService in several files. For example, look at owlconverter:ImportOntologyFromOWLFile from the file teamwork.topbraidlive.org/api/owlconverter.api.ttl.

Instructions

You need to create a workspace file ending with .api.ttl and declare an instance of dash:GraphConstructorService in it. Typically you would use TopBraid EDG Studio for its development and later upload the resulting file to a production instance. Follow the comments on that class and its properties to understand how to use them.

Asset Collection Constructors (Old)

This extension point can be used to install scripts that are triggered whenever a new asset collection (of certain types) is created, for example to initialize the state of the new asset collection.

Note

For many use cases, going through Asset Collection Constructors is a better choice, and this extension point here uses an older technology, SWP, instead of modern JavaScript.

Samples:

Instructions:

In a .ui.ttlx file, make sure that teamwork.ui.ttlx is included so that the property teamwork:projectConstructor is defined. These constructors need to be linked to specific asset collection types using that property.

The following table lists the supported asset collection types and the files in which they are defined. For example, in order to add a constructor for Taxonomies, add an owl:import of the file teamwork.topbraidlive.org/taxonomy/taxonomyprojects.ui.ttlx and then add a triple taxonomies:ProjectType teamwork:projectConstructor [ ex:ExampleProjectConstructor ] using the Source Code panel.

TopBraid EDG Collection Types

Collection Type Name

Collection Type Resource

File Path of Defining Graph

Content Tag Set

taggerprojects:ProjectType

teamwork.topbraidlive.org/tagger/taggerprojects.ui.ttlx

Crosswalk

taxonomies:ProjectType

teamwork.topbraidlive.org/taxonomy/taxonomyprojects.ui.ttlx

Data Graph

datagraphprojects:ProjectType

teamwork.topbraidlive.org/datagraph/datagraphprojects.ui.ttlx

Datatypes Collection

edg:DatatypesProjectType

edg.topbraidlive.org/1.0/controller/CONTROLLER_EDG-datatypes-v1.0.ui.ttlx

Enterprise Assets Collection

edg:EnterpriseModelsProjectType

edg.topbraidlive.org/1.0/controller/CONTROLLER_EDG-enterprise-assets-v1.0.ui.ttlx

Enumeration Collection

edg:EnumerationsProjectType

edg.topbraidlive.org/1.0/controller/CONTROLLER_EDG-ENUMERATIONS-v1.0.ui.ttlx

File

teamwork:FileProjectType

teamwork.topbraidlive.org/file/teamworkfiles.ui.ttlx

Glossary

edg:GlossaryProjectType

edg.topbraidlive.org/1.0/controller/CONTROLLER_EDG-common-v1.0.ui.ttlx

Governance Assets Collection

edg:GovernanceModelProjectType

edg.topbraidlive.org/1.0/controller/CONTROLLER_EDG-governance-assets-v1.0.ui.ttlx

Lineage Model

edg:LineageModelProjectType

edg.topbraidlive.org/1.0/controller/CONTROLLER_EDG-lineage-models-v1.0.ui.ttlx

Ontology

ontologyprojects:ProjectType

teamwork.topbraidlive.org/ontology/ontologyprojects.ui.ttlx

Reference Dataset

rdmprojects:ProjectType

teamwork.topbraidlive.org/dataset/datasetprojects.ui.ttlx

Requirements Collection

edg:RequirementsModelProjectType

edg.topbraidlive.org/1.0/controller/CONTROLLER_EDG-requirements-model-v1.0.ui.ttlx

Taxonomy

taxonomies:ProjectType

teamwork.topbraidlive.org/taxonomy/taxonomyprojects.ui.ttlx

Technical Assets Collection

edg:TechnicalAssetsProjectType

edg.topbraidlive.org/1.0/controller/CONTROLLER_EDG-technical-assets-v1.0.ui.spin.ttlx

Note

Your installation may not include licenses for all of those collection types.

Asset Collection Clone Plugins

This extension point can be used to install scripts that execute whenever an asset collection has been cloned, for example to modify the clone before its first use.

Samples:

In a .ui.ttlx file, make sure that teamwork.ui.ttlx is included so that you can create a subclass of teamwork:ClonePlugin. In that subclass use dash:js to store the ADS script that shall be executed when an asset collection gets cloned. In those scripts, you can use the variables oldProjectGraph and newProjectGraph to query the uri of the source and target of the clone operation. You can use this, for example, to look up the type of the old or new asset collection to decide what actually needs to happen with the clone.

Custom Asset Collection Types

This extension point can be used to define new Asset Collection types in addition to the built-in types (such as Taxonomies).

Instructions:

All collections of the same type share the same features.

Note

Defining custom collection types is a licensed feature of EDG. While you will be able to develop and test new project types in TopBraid EDG Studio, once you deploy your code to the EDG server, new types of collections will only be available if your solution is licensed for creation of new asset collection types. To upgrade your license, please contact TopQuadrant.

Each of the default collection types that come with TopBraid EDG are plug-in modules within the more general Teamwork Framework. It is possible to add new modules by creating an instance of the class teamwork:ProjectType in a globally registered file ending with .ui.*. This file should import the file teamwork.ui.ttlx.

Simply create an instance of teamwork:ProjectType and fill in the properties similar to how it’s done in the default Ontology asset collection type (from ontologyprojects.ui.ttlx). You need to enter values for teamwork:singularLabel and teamwork:pluralLabel. You also need to create a new subclass of the teamwork:Vocabulary class and enter it as the value for the teamwork:vocabularyType. For the ontology asset collection type, this value is ontologyprojects:Ontology.

Hint

Use the Source Code panel where required, for properties that don’t show up on the form.

Also include the file edg.topbraidlive.org/edgproduct.ui.ttlx. Under teamwork:Product select the one instance for EDG (edgproduct:EDG) and add your new project type to the teamwork:defaultProjectType property. This makes sure your new teamwork:ProjectType visible in EDG.

Adding a New Panel to the Editor Applications

The EDG Editor application is developed using React and a front-end build process. The Editor offers a choice of pre-built panels that can be organized into page layouts.

You can add your own custom panels to the editor. New panels will be available to users in exactly the same way as pre-built panels. In order to create new custom panels you will need to be familiar with RDF, React, WebPack and Babel.

We have prepared a sample guide and sample project that adds a new panel to the editor. Please download the guide and sample zip file below to get started.

Adding new Java Components

It is technically possible to inject new Java components into TopBraid EDG servers. This is, obviously, a very low-level operation and only recommended for very experienced developers. As our Java code is not open source, this will most likely require hand-holding. We strongly recommend to use Premium Support hours for such endeavours.

To get an idea, see this thread on the TopBraid users mailing list.