General Interface is an open source project hosted by the Dojo Foundation

Plug-ins with Extensions and Extension Points

This section describes the AMP plug-ins, extensions, and extension points.

Plug-Ins

Each AMP application comprises a set of AMP plug-ins, the functional units of an AMP application. As a developer, you decide how to decompose the application into its constituent plug-ins. Consider plug-ins to be application components that are either present (loaded) or absent (unloaded). In other words, design cohesive plug-ins that contain the parts of the application that function together, and tie plug-ins loosely to each other.

When decomposing an application, keep in mind that an AMP application loads at the granularity of plug-ins; by default, all parts of a plug-in are loaded together.

Plug-ins are defined with a plugin.xml descriptor file. Each plug-in has a unique identifier that is also the name of the directory in which the plugin.xml file is placed.

In the following example, the plug-in identifier is com.tibco.example.p1.

<plugin xmlns="http://www.tibco.com/gi/amp"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.tibco.com/gi/amp
http://gi.tibco.com/xsd/plugin.xsd"
        id="com.tibco.example.plugin"
        name="Example Plug-In"
        version="0.1">
    ...
</plugin>

To register plug-ins, refer to them in the plugins.xml file, and place the file in the plugins directory at the root of the General Interface application that uses AMP. Alternatively, you can use the AMP API to register plug-ins programmatically. For each plug-in registered in the plugins.xml file, there should be a directory in the plugins directory with a name equal to the ID of the registered plug-in. Each of these directories should contain a plugin.xml file.

<plugins xmlns="http://www.tibco.com/gi/amp"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.tibco.com/gi/amp">
<plugin id="com.tibco.example.p1"/>
...
</plugins>

The following figure shows the plugins directory structure.

You can locate the directory of a plug-in outside of the application's plugins directory. In this case, the path attribute of the plugin element should be the relative path from the plugins directory to the directory that contains the plugin directory.
<plugins>
    <plugin id="com.tibco.example2.plugin" 
      path="../../otherApp/plugins/"/>
    ...
</plugins>

Extension Points and Extensions

A plug-in defines extension points and extensions. An extension point is an interface or contract between the plug-in that defines it and any extension that extends it. The form of this contract is loosely defined in AMP itself. It is a developer decision whether the contract takes the form of an XML schema, a JavaScript interface, or both.

An extension point is often designed to accept any number of extensions (one-to-many) but can also be designed to accept only one extension (one-to-one) or a specified number of extensions. The cardinality is not specified declaratively; it is enforced by the JavaScript code that processes the extensions.

An extension point is declared in a plug-in descriptor file.

<plugin id="com.tibco.example.p1"/>
  <extension-point id="example-xp"/>
</plugin>

An extension is a concrete implementation of the extension point contract. You can define an extension in the same plug-in that defines its extension point or in another plug-in. In both cases, the point attribute of the extension element is the fully-qualified identifier of the extension point. The fully-qualified identifier is the id attribute of the extension-point element appended to the identifier of its plug-in and separated with a period (".").

<plugin ...>
  <extension point="com.tibco.example.p1.example-xp">
    ...
  </extension>
</plugin>

The extension point-extension relationship is loosely coupled and controlled by the extension point. It is possible for an extension to extend an extension point that is not registered. Similarly, it is usually acceptable for an extension point to have no extensions.

Plug-in Resources and the Plug-in Life Cycle

Plug-ins comprise the plugin.xml descriptor file and a collection of resources, which can be JavaScript, CSS, XML, XSL, or JSS properties, or properties bundles. These reside in the plug-in's directory and are referenced within the descriptor file, as in the following example.

<plugin ...>
    <resources>
        <script id="js" path="logic.js"/>
        <xml id="xml" path="data.xml" load="manual"/>
        ...
    </resources>
</plugin>

Resources can declare a load setting with the load attribute, as in the example above. The possible values are early, normal (the default value), and manual. The load setting affects when the resource is loaded in relationship to the plug-in life cycle.

AMP plug-in life cycle follows this process:

  1. An AMP engine is instantiated for every AMP application.
  2. The AMP engine processes plug-ins in the order that they are listed in the plugins.xml registry file.
  3. For each plug-in, the following apply:
    1. Plug-in resources designated for early loading are loaded first.
    2. The plug-in is instantiated and registered. Its onRegister() method is called. At this point, some of the extensions to the plug-in's extension points may not be registered.
    3. As the rest of the plug-ins are registered, the plug-in's onExtension() method is called each time a plug-in is registered that extends one of its extension points.
  4. After all plug-ins have been registered, the AMP engine is considered to be loaded and it publishes its LOAD event.
  5. If and when the load() method is called on a plug-in, all of its normal loading resources are loaded, after which the plug-in is considered to be loaded, and its onLoad() method is called.
  6. After the plug-in is loaded, any manual loading resources can be loaded programmatically.

You can also define resources inline in the plugin.xml file. Instead of defining the path attribute, you can nest the file contents in a <data> element inside the resource element. For JavaScript and CSS resources, the nested <data> element is optional; for example, you can define a script in the text content of the <script> element.

The inline resource definition must be valid XML. Characters that are valid JavaScript or CSS but invalid XML must be properly encoded. Consider using a CDATA block for better readability.
<resources>
  <script id="js"><![CDATA[
    this.getLog().info("Loaded resource js.");
  ]]></script>
</resources>

XML, XSL and dynamic properties resources are defined inline as a document fragment. When defining these resources inline, make sure that you define the correct XML namespace for the content. If the xmlns attribute is not specified, the document fragment will inherit the AMP XML namespace.

<resources>
  <xml id="info">
    <data>
      <info xmlns="">
        <item id="1"/>
      </info>
    </data>
  </xml>
</resources>

Prerequisites and Load Order

Plug-ins and resources can define dependencies that enforce a load order. You must declare dependencies in order for the load order of application resources to be well-defined.

A plug-in can depend on another plug-in by declaring that it requires it in its descriptor file. When a plug-in requires another plug-in, then the required plug-in will load (step 5, above) before the requiring plug-in. In addition, the required plug-in is instantiated before the requiring plug-in. This means that all early load resources of the required plug-in are loaded before the early load resources of the requiring plug-in.

<plugin id="com.tibco.example.p1">
    <requires>
        <plugin id="com.tibco.example.lib"/>
    </requires>
    ...
</plugin>

Similarly, a resource may require that another resource be loaded before it is loaded. A resource can also declare that a plug-in loads before the resource. This second option is useful for manual load resources for which the plug-in does not declare the dependency. In the following example, the com.tibco.example.lib plug-in loads before logic.js and logic.js loads before SampleClass.js.

<plugin id="com.tibco.example.p1">
    <resources>
        <script id="js" path="logic.js">
            <prereq plugin="com.tibco.example.lib"/>
        </script>
        <script id="SampleClass" path="SampleClass.js">
            <prereq id="js"/>
        </script>
    </resources>
    ...
</plugin>

Contents

Searching General Interface Docs

Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.