Extending Redwood Server Functionality with Extension Points
You can create custom user interface add-ons with extension points. Extension points hook into the user interface and allow you to create custom dialogs. For example, you could create an extension on JobDefinition to display a dialog with specific properties of selected processes.
Extension points are comprised of RedwoodScript code that evaluates the content of the dialog and a Deployment Descriptor that defines where the controls are in the user interface. The visibility of the extension point governs the accessibility; a visibility of External or Both makes the extension available externally via a URL. Internal and Both extension points typically integrate into the tool bar or the context-menu. These extensions are available under the Extensions context-menu item.
The following extension point types are available:
- Internal extension points
- External extension points, accessible externally without authentication
- Internal and external extension points (specified as Both ), accessible externally without authentication
- Remote extension points
Prerequisites
- License key
Module.ExtensionPoint
set totrue
Fields and Tabs
Tab | Field | Description |
---|---|---|
Extension Point | Partition | The partition of the extension point |
Extension Point | Name | The name of the extension point |
Extension Point | Description | The description of the extension point |
Extension Point | Application | The application of the extension point |
Extension Point | Visibility | The visibility of the extension point Internal extensions are only available from inside Redwood Server External extensions are only available via a URL Extensions with visibility set to Both are accessible from the interface and URL's |
Extension Point | Log Level | Verbosity of the logging. Trace, Debug, Info, Warn, Error, Fatal, or None. |
Extension Point | Max Backup Files | Maximum number of log files to create. |
Extension Point | Max Log Size | Maximum size of the log files. |
Extension Point | Action Subject | The subject as which the extension point code should be executed as. |
Extension Point | Library | Optional library containing code called by the extension |
Extension Point | Source | The source code of the extension point |
Extension Point | Variables | List of predefined variables available in the extension point source. |
Documentation | Documentation | Free text information about the extension point |
Deployment Descriptor | An XML document that describes the hooks the extension point uses in Redwood Server | |
Security | * | Users that can use the extension |
Internal Extension Points
Internal extension points extend the user interface and allow you to design custom toolbar buttons and/or additional items in the context-menus of objects.
External Extension Points
External extension points are servlet-like objects that are made available under the following URL:
http[s]://<server>:<port>/redwood/api-extension/<Visibility>/<Partition>/<name>
For example:
https://pr1.example.com:53000/redwood/api-extension/External/GLOBAL/MSLN_JobsInError
External extension points are accessible at the above URL without authentication; this means that the unauthenticated user can perform actions in Redwood Server as specified in the extension point, running as the action subject of the extension point.
The Document servlet is not accessible to external or both extension points; this limitation has been introduced for security reasons.
Remote Extension Points
Remote extensions query remote URL's; you use these to retrieve output from remote systems or send the output of the extension to remote servers, for example.
Source Code
The following table lists the implicit objects that are available in the source of the extension point.
Implicit Objects | Class |
---|---|
jcsExtensionPointContext | ExtensionPointScriptObject (Extensions on View) |
jcsOutLog | Logger |
jcsParameters | jcsParameters |
jcsSession | jcsSession |
jcsRequest | jcsRequest |
jcsUserSession | jcsUserSession |
jcsResponse | jcsResponse |
Deployment Descriptor DTD
<!--Define extensions-->
<!-- An internal extension point is indicated by starting the xml with extension point -->
<!ELEMENT extensionpoint ((extension)+)>
<!--
version: for the author, is not used internally.
-->
<!ATTLIST extensionpoint version CDATA #REQUIRED
>
<!-- A single extension point can have multiple extends, allowing to define multiple entries in one file -->
<!ELEMENT extension (description, extends, parameters*, translations+)>
<!--
name: name of the extension, so they can be differentiated in the code. Will be passed through the executing code.
output: where should the output of the extension be displayed
-->
<!ATTLIST extension name ID #REQUIRED
output (popup|tabpage|mainpage|homepage) #REQUIRED
>
<!-- A remoteextension is used for extension points that are not hosted by cronacle. The deployment descriptor they provide must start with the remoteextension element in the xml -->
<!ELEMENT remoteextensionpoint (remoteextension)+>
<!--
version: for the author, is not used internally.
ttl: defines how often the deployment descriptor should be refreshed. Time is in minutes, default is once every hour.
-->
<!ATTLIST remoteextensionpoint version CDATA #REQUIRED
ttl CDATA "60"
>
<!-- A remoteextensionpoint defines one or multiple remoteextension elements. They have an additional element, target, that defines where to send the request to -->
<!ELEMENT remoteextension (target, description, extends, parameters*, translations+)>
<!--
name: name of the remoteextension, so they can be differentiated in the code. Will be passed through the executing code.
output: where should the output of the extension be displayed
-->
<!ATTLIST remoteextension name ID #REQUIRED
output (popup|tabpage) #REQUIRED
>
<!--
The target element defines what URL to contact when the user selects the remoteextension.
The target is resolved in the context of the original URL as defined in the registry for this extension point.
This means that relative URLs can be provided. See the javadoc for java.net.URL(UTL, String) for more information
-->
<!ELEMENT target (#PCDATA)>
<!--Description of what the extension provides-->
<!ELEMENT description (#PCDATA)>
<!--Where should the extension be shown in the user interface-->
<!ELEMENT extends (((popupmenu|toolbar|outputview)*|definitionselector|parametereditor),main?,navigationbar?)>
<!-- The singlesession attribute defines whether each call to open the same extension point should use the same session/instance or open a new instance. -->
<!ATTLIST extends singlesession (true|false) "false">
<!-- Which parameters should be sent over when the user selects the extension point -->
<!ELEMENT parameters (model|constant)*>
<!-- Provide translations to be shown in the ui -->
<!ELEMENT translations (translation*)>
<!--
default: the default language to use when no match could be made with the current user settings
-->
<!ATTLIST translations default CDATA #REQUIRED>
<!-- A popupmenu element defines which popup menus in the ui should get the extension point sub menu for this extension point
Filters can be specified that must all match in order for the popupmenu to be visible for that element
-->
<!ELEMENT popupmenu (filter*)>
<!--
objecttype: is the SchedulerEntity object type that must match. This can also be an abstract class like NamedRootObject
multiselect: if the menu is on an overview, should it also be shown when multiple items are selected
-->
<!ATTLIST popupmenu objecttype CDATA #IMPLIED
multiselect (true|false) "false"
>
<!-- An outputview element defines which job files should be directed to this output view. This ignores the output attribute of extends.
Filters can be specified that must all match in order for the output view to be used.
Specifying no filters means the viewer will be used for all job files.
-->
<!ELEMENT outputview (filter*)>
<!-- A definitionselector element overwrites job chain editor JobDefinition selector.
Filters can be specified that must all match in order for the definition selector to be used.
Specifying no filters means the selector will be used for all job definitions.
-->
<!ELEMENT definitionselector (filter*)>
<!--
DisableControl (optional) is to specify whether the original control of definitionselector is suppressed.
If attribute disablecontrol is not provided, a default of "true" will be used.
-->
<!ATTLIST definitionselector disablecontrol (true|false) "true">
<!-- A parametereditor element overwrites job chain editor parameter expression fields. -->
<!ELEMENT parametereditor (#PCDATA)>
<!--
DisableControl (optional) is to specify whether the original control of parameter editor is suppressed.
If attribute disablecontrol is not provided, a default of "false" will be used.
-->
<!ATTLIST parametereditor disablecontrol (true|false) "false">
<!-- toolbar element will show an icon on the toolbar for a given page, either a show page or overview for the given object type -->
<!ELEMENT toolbar (icon)>
<!--
objecttype: is the SchedulerEntity object type that must match. This can also be an abstract class like NamedRootObject
useselection: should the selected objects (overview) or the single object (show page) be send to the executing code
-->
<!ATTLIST toolbar objecttype CDATA #IMPLIED
useselection (true|false) "false"
>
<!-- The main defines an icon on the toolbar that is always shown. -->
<!ELEMENT main (icon)>
<!-- The navigationbar defines an entry on the navigationbar in the custom group. -->
<!ELEMENT navigationbar (icon)>
<!-- The filter specifies the criteria that the object must match in order for it to be shown. If multiple filters are defined then
all must be true in order for it to be shown.
The attributes specify field and comparison type, the value of the element is the value that will be matched.
This value can contain the wildcards ? for any single character and * for any sequence, including an empty sequence.
-->
<!ELEMENT filter (#PCDATA)>
<!--
field: is the field that should be compared. A path can be specified with . to continue traversal on linked objects. F.e. to get compare the name of the
parent Application of a JobDefinition, the path ParentApplication.Name can be entered. Traversing Collections is not supported.
compare: what type of comparison should be made. EQUALS equates to == , NOTEEQUALS to != , NULL to == NULL and NOTNULL to != NULL
-->
<!ATTLIST filter field CDATA #IMPLIED>
<!-- We can filter on either field or objecttag -->
<!ATTLIST filter objecttag CDATA #IMPLIED>
<!ATTLIST filter compare (EQUALS|NOTEQUALS|NULL|NOTNULL) #REQUIRED>
<!-- The model element defines a variable that is provided by a scheduler entity -->
<!ELEMENT model EMPTY>
<!--
name: the name of the property from the scheduler entity. Valid names are what com.redwood.scheduler.api.runtime.RuntimeClass.getMembers() returns for the given object type
encoding: How should the value be encoded when sending to the executing code. At this point no encodings have been defined
-->
<!ATTLIST model name CDATA #REQUIRED
encoding CDATA #IMPLIED
>
<!-- The constant element defines addition parameters that will be send to the executing code. This is for the author only, is not used internally other then passing it through -->
<!ELEMENT constant (#PCDATA)>
<!--
name: the name of the property from the scheduler entity. Valid names are what com.redwood.scheduler.api.runtime.RuntimeClass.getMembers() returns for the given object type
-->
<!ATTLIST constant name CDATA #REQUIRED>
<!-- The translation element provides the translation for the extension point -->
<!ELEMENT translation (#PCDATA)>
<!--
lang: the language for which this translation is valid. Will be match against java.util.Locale.getLanguage() of the users language setting
-->
<!ATTLIST translation lang CDATA #REQUIRED>
<!-- The icon defines which url to use for displaying the icon. doc: links are also allowed and will be resolved against Document objects.
The provided icon should be 32x32 pixels to make sure it gets displayed correctly. -->
<!ELEMENT icon (#PCDATA)>
Partitions
You specify $
for partitions for resources, they will be retrieved from the partition of the extension point.
So the following img tags will all resolve to the document doc:Partition1:/testapplication/test/image.png based on an Extension Point in Partition1 with application path testapplication/test:
<img src="doc/$:/$/image.png">
<img src="doc/Partition1:/$/image.png">
<img src="doc/$:/testapplication/test/image.png">
<img src="doc/Partition1:/testapplication/test/image.png">
The following URL's will NOT work:
<img src="doc/$/image.png"> : Partition is missing, and it defaults to GLOBAL, so the document will not be found.
<img src="doc/$:/image.png"> : Application path is missing, and will default to "", so the document will not be found.
<img src="doc/image.png"> : Both Partition and Application paths are missing, will default to GLOBAL and empty path, so document will not be found.
Dynamic Toolbar Icons
The icon
property takes a URL, document path, or REL expression to an icon. The REL expression must start with a =
and is evaluated once every 60 seconds by default. You set the /configuration/ui/ToolbarRefreshRate registry entry to customize the interval. The minimum interval is 30
seconds.
ObjectTagDefinition
ObjectTagDefinitions customize the behavior of objects, such as extension points, and prevent you from performing certain actions on the tagged objects.
See Also
Extension points