Appendix A. How to adapt an existing ".xxe" configuration file to XXEW Previous topic Parent topic Child topic Next topic

Like XXE, the desktop app, xxeserver scans the XXEW_install_dir/addon/ and XXE_user_preferences_dir/addon/ add-ons directories during its startup and load configurations Opens in new window from there.
Unlike XXE, xxeserver automatically skips certain configuration elements (<binding> Opens in new windows other than keyboard bindings, <attributeVisibility> Opens in new window, <elementVisibility> Opens in new window, <documentSetFactory> Opens in new window), certain configuration files ("MathML support", "XMLmind XML Editor Configuration Pack", etc) and certain add-on categories ("spell checker dictionaries", "spell checker plug-ins", "XSL-FO processor plug-ins", etc) because these are either not useful in the context of XXEW or because these are not yet supported by XXEW. Moreover, XXE features Opens in new window are not enabled in xxeserver. For example, the ConvertDocument feature is not enabled, therefore <xxe-client> has no "Convert Document" submenu.
Restriction
Restriction
There is currently no way to force a running xxeserver to reload one or all of its configurations.
Therefore you can very easily make XXEW reuse existing configurations created for XXE or if you want to create a configuration for XXEW, simply follow the instructions which apply to XXE Opens in new window.
There is one big restriction though: interactive commands, that is, commands written in Java™ displaying Java dialog boxes, won't work in XXEW.
Note
Note
What happens in <xxe-client> if the user invokes a interactive Java command which has not yet been “ported” to JavaScript™? Not much. If the command is found in a menu or toolbar, the corresponding menu item/toolbar button will generally be disabled and the user will not be able to invoke the command. At worse, if the user manages to invoke the command, the command will do nothing at all.
Fortunately there is a simple way to mark parts of a configuration file as being specific to XXEW or, on the contrary, as being specific to XXE. This way some configuration elements are used only when the file is loaded by xxeserver and other configuration elements are used only when the file is loaded by the desktop app.

Conditional processing of configuration files

It's strongly recommended to use the following processing-instructions Opens in new window to mark parts of a configuration file as being specific to XXEW or, on the contrary, as being specific to XXE:
<?if TEST?>
...configuration elements...
<?else?>
...configuration elements...
<?endif?>
  • TEST is XXE_CLIENT for configuration elements which are specific to XXEW and !XXE_CLIENT for configuration elements which are specific to XXE.
  • The <?else?> directive is optional.
Use this facility to mark
  • interactive command declarations,
  • macro command definitions invoking interactive commands,
  • menu items, toolbar buttons, bindings invoking interactive commands,
  • and more generally any functionality which is not useful in the context of XXEW
as being specific to XXE.
DocBook examples (excerpts from XXEW_install_dir/addon/config/docbook/docbook.xxe):
<?if !XXE_CLIENT?>
...
<command name="docb.editImageMap">
  <class>com.xmlmind.xmleditext.docbook.EditImageMap</class>
</command>
<?endif?>

<command name="{docb}setLinkEnd">
  <macro>
    <sequence>
      <test context="$implicitElement" expression="is-editable()" />

      <set variable="selectedElement" context="$implicitElement" 
           expression="(ancestor-or-self::*[@%0])[last()]" />

      <?if XXE_CLIENT?>
      <command name="stop"
               parameter="xxeClientExecuteCommand editAttributes %0" />
      <?else?>
      <command name="putAttribute" parameter="%0" />
      <?endif?>
    </sequence>
  </macro>
</command>

<menu label="_DocBook">
  <?if !XXE_CLIENT?>
  <item label="Upgrade to DocBook _version 5..."
        command="docb.toV5"/>
  <separator/>
  <item label="_Set up olinks..."
        command="docb.olinkedDocuments"/>
  <separator/>
  <?endif?>
  ...
</menu>

Adapting an interactive macro to XXEW

In some cases, a menu command Opens in new window or a macro command Opens in new window ending with an interactive command can be easily ported to XXEW by the means of the stop command.
The stop command is specific to XXEW and does not exist in XXE. It's a very simple command which stops the execution of the macro and returns to its invoker a STOPPED status Opens in new window and its parameter as the result of the command.
In the above {docb}setLinkEnd macro, "putAttribute attribute_name", which is an interactive Java command, has been replaced by "stop xxeClientExecuteCommand editAttributes attribute_name".
By convention, when <xxe-client> invokes a remote command (here it's {docb}setLinkEnd) and this command stops and returns a result which starts with "xxeClientExecuteCommand", then <xxe-client> invokes the command specified in this result.
In above example, editAttributes is an interactive command written in JavaScript which is the XXEW equivalent of interactive Java command editAttributes Opens in new window.
Other DocBook example:
<command name="{docb}linkMenuItems2">
  <menu>
    <?if !XXE_CLIENT?>
    <item label="Follow Link" 
          command="start" parameter="helper(defaultViewer) '%*'" />
    <?else?>
    <item label="Follow Link" command="stop"
          parameter="xxeClientExecuteCommand openExternalLink %*" />
    <?endif?>
    <item label="Set Link Target..." 
          command="{docb}setLinkEnd" parameter="url" />
  </menu>
</command>

“Porting” an interactive Java command to XXEW

Reading the following section should give you an idea on how difficult it is to “port” an interactive Java command to XXEW. It's by no mean a detailed, step by step, tutorial.
Let's use DocBook command LinkCallouts as an example. This interactive Java command, found in the DocBook menu Opens in new window, links a sequence of <callout> elements to the corresponding sequence of <co> or <area> elements (and, of course, also the other way round).
item.png First of all, the server-side, interactive Java command must be made “portable” to XXEW. This is the case of LinkCallouts because:
  • The command may be used interactively as well as non-interactively.
    When passed an ID prefix as its parameter, LinkCallouts does its work and modify the document being edited without having to display its Java dialog box.

    Figure A-1. The Java dialog box displayed by command LinkCallouts when used interactively

    link_callouts_java_dialog.png
  • The command can be executed on computers having no display (typically when the command is invoked by xxeserver(1)).
    LinkCallouts tests whether it can display its Java dialog box. When displaying a dialog box is needed and this is not possible, instead of just failing, LinkCallouts returns a STOPPED status Opens in new window and the result of the command contains all the information needed to populate the dialog box it would have displayed.
    Component dialogParent = docView.getDialogParent();
    ...
    if (dialogParent == null) {
        // Cannot prompt user.
        return CommandResult.stopped Opens in new window(stoppedValue(
            prefix, discardExistingXRefs, lockDiscardExistingXRefs));
    } else {
        // Prompt user for an ID prefix.
        PrefixDialog dialog = new PrefixDialog(dialogParent);
        Object[] result = dialog.getPrefix(prefix, discardExistingXRefs,
                                           lockDiscardExistingXRefs);
        if (result == null) {
            return CommandResult.CANCELED;
        }
        ...
item.png The second effort consists in implementing a client-side, interactive JavaScript command, displaying a dialog box written in HTML+CSS+JavaScript, having the same registered command name as its Java counterpart.
This client-side command is implemented by JavaScript class LinkCalloutsCmd and it is declared to <xxe-client> as being docb.linkCallouts (for use by DocBook 4 documents) and db5.linkCallouts (for use by DocBook 5+ documents). Excerpts from XXEW_install_dir/web/webapp/xxeclient/docbook.js:
class LinkCalloutsCmd extends XXE.InteractiveRemoteCommand {
    constructor(commandName) {
        super(commandName);
    }

    resumeExecution(mode, docView, params,
                    stoppedCommandInfo, resolve, reject) {
        // stoppedCommandInfo syntax is:
        // 'discard'|'keep' [ '!' ] [ ';' prefix ]

    ...
}

for (let n of [ "docb.linkCallouts", "db5.linkCallouts" ]) {
    XXE.ALL_LOCAL_COMMANDS[n] = new LinkCalloutsCmd(n);
}
Like all XXE.InteractiveRemoteCommand Opens in new windows, LinkCalloutsCmd functions as follows:
  1. It invokes the remote, that is, server-side, Java, command having the same name (e.g. docb.linkCallouts, implemented by Java class LinkCallouts) without any parameter.
  2. After receiving the result of the remote command (in method resumeExecution()), normally a STOPPED status and a result value containing all the information needed to populate a dialog box (an ID prefix, if any, and other settings in the case of docb.linkCallouts), LinkCalloutsCmd displays its HTML+CSS+JavaScript dialog box.

    Figure A-2. The HTML+CSS+JavaScript dialog box displayed by command LinkCalloutsCmd

    link_callouts_js_dialog.png
  3. Unless the user cancels this dialog box, LinkCalloutsCmd invokes one more time remote command docb.linkCallouts, but this time with a parameter containing the ID prefix and the other settings specified by the user in the dialog box.
  4. Remote command docb.linkCallouts having all needed information to do its job, modifies the document accordingly and returns an DONE result, which is returned as is as the result of LinkCalloutsCmd.

 (1) xxeserver is designed to run on computers having no display hence xxeserver is started with -Djava.awt.headless=true.