Tuesday, August 05, 2014

The Oxygen SDK (Part 2: Frameworks)

Share to Facebook Share to Twitter Email This Share on Google Plus Share on Tumblr
This is the second part of a blog post I started some time ago:

There are two ways of customizing the application, by implementing a plugin or by implementing a framework:

A framework configuration provides validation, content completion and editing support for a certain XML vocabulary. 

If you are already using Oxygen for editing DITA, Docbook, XHTML or TEI documents you may notice that Oxygen knows how to validate these vocabularies and that it can propose content completion entries while you are editing. Also when you are editing in the Author visual editing mode you have lots of custom vocabulary-specific toolbar buttons which can be used to insert links, images, to manipulate tables and so on. This happens because each Oxygen installation comes with pre-bundled framework configurations for certain XML vocabularies that we consider to be more important for our users.

Knowing how to create and modify a framework/document type association configuration will benefit you in two ways:
  1. Create your own framework which adds editing support to Oxygen for certain specific XML vocabularies and then distribute it to your team.
  2. Customize an existing framework bundled with the installation (DITA, Docbook, etc) and change certain behaviors in it.
Our user manual contains a special step by step tutorial which explains how a new framework configuration (document type association) can be created and configured:
The Oxygen Preferences->Document Type Association page lists all detected frameworks (document type associations). Usually looking inside one of the pre-configured document type associations (eg: DITA) is a good place to start exploring what such a customization contains:
  1. Association rules - when one of these rules matches the opened XML document, Oxygen will associate it with the current document type association. The rules are pretty simple to compose, they refer to a certain root name, namespace, certain attributes set on the root and so on.
  2. Schema - specifies a grammar to be used to providing validation and content completion if the opened XML document does not refer directly to any particular gramar.
  3. Classpath - a list of JAR libraries which contain Java extensions for this specific framework.
  4. Author - contains all necessary support for editing the XML in the Author visual editing mode:
    • CSS - one or more CSS files to be used when rendering the XML. If you define alternate CSSs, you will be able to switch between them when editing. The user manual contains a list of supported CSS features and additional available extensions.
    • Actions - a list of actions specific for modifying the edited content. An action has a name, description, icons and shortcut key. It also has one or more activation contexts which depending on an XPath expression enable a certain operation be be executed. A fair amount of basic operations are already available but you can create your custom operations.
    • Menu, Contextual menu and Toolbar - you can easily mount defined actions to the main document type menu, to the contextual menu or to the special Author toolbar(s).
    • Content Completion - add defined actions to the content completion window (shown when ENTER is pressed in the Author editor mode) or remove existing entries from the content completion window. You can for example replace some of the insert suggestions given by the association grammar with your own custom actions.
  5. Templates - points to folders which contain new file templates for this particular framework. These new file templates will be shown in the New wizard dialog.
  6. Catalogs contains a list of XML catalogs which will be used to indirectly solve various references (like references to schemas or other XML documents).
  7. Transformation may contains a predefined list of transformation scenarios which are available when you want to publish your opened XML document to various output formats.
  8. Validation may contain a predefined list of validation scenarios which are used to add complex multi-stage validation (with multiple engines) for the XML documents matching the document type association.
  9. Extensions - contains implementations of the available Java extensions which are used to provide further functionality for editing in the Author visual editing mode. Here's what some of the extensions do:
    • AuthorExtensionStateListener - provides a way to be notified when the XML was opened in the Author editing mode. You can then add all kinds of listeners and react to edit events done by the user. For example add a modification listener, send the edited content to an external spell checker engine and then add highlights in the content on invalid constructs.
    • AuthorExternalObjectInsertionHandler - reacts to drag and drop and copy/paste events containing with HTML content or resources. In the case of DITA for example this handler is responsible of the automatic conversion of HTML pasted from the browser to DITA content.
    • SchemaManagerFilter - filter and modify the insertion items detected from the associated grammar when editing XML content. For example even if the schema proposes certain elements as valid insertions at the caret offset, you can filter out and restrict the suggestions given by the associated schema (grammar).
    • StylesFilter - take control over the rendering styles for each node by adding this layer of Java customization over the styles provided by the associated CSSs.
    • AuthorSchemaAwareEditingHandler - handle special editing cases and provide fallbacks which keep the document in a valid state. For example if the user starts typing text between two paragraphs, the handler can automatically create a new paragraph.
You can create automated tests for your frameworks:

and even debug their functionality:

4 comments:

  1. Hi Radu,

    I have developed a framework with a schema association, a toolbar, menu, custom actions in Java and CSS rules. Now it seems that I also need to create a plugin (of the Workspace Access type; I want to be notified about files being opened and closed). Now I wonder about the best way to proceed:
    - Should I give my users both a plugin and a framework
    - or can I convert the existing framework to a plugin?

    If converting the framework to a plugin is the best or nicest option, is there a way to easily reuse the framework configuration work that has already been done using the Oxygen facilies of Preferences->Document Type Association? I found that very convenient, much more convenient, it seems, than configuring the same thing in Java.

    ReplyDelete
  2. You cannot convert a framework to a plugin so your users would need to install both the plugin and the framework.
    About your use case, if you edit your document type configuration, in the "Extensions" tab you can set a Java extension called "Author extension state listener" (an implementation of the interface "ro.sync.ecss.extensions.api.AuthorExtensionStateListener") which is called when a document is opened in the Author visual editing mode.
    On the "activated" callback you can use our singleton workspace access to add an editor opened listener:
    PluginWorkspaceProvider.getPluginWorkspace().addEditorChangeListener(..., PluginWorkspace.MAIN_EDITING_AREA);

    but you would need to remove the listener on the "deactivated" call which occurs when the XML document is closed or when it is switched to the Text editing mode.
    You need to take into account that for each opened XML document there will be a separate "AuthorExtensionStateListener" instance.

    ReplyDelete
  3. I just tried out your advice - it is excellent! Thanks a lot!

    Pieter

    ReplyDelete
  4. Hello,

    I just wanted to say one thing related to frameworks and plugins in oXygen. In the newly released oXygen 19.0 you can contribute frameworks from plugins. Some more info at https://www.oxygenxml.com/doc/versions/19.0/ug-editor/topics/additional-framework-extension.html?hl=additional%2Cframework%2Cplugin%2Cextension.

    ReplyDelete