4.3. Integrating the applet with your web application
Prev | 4. Deploying XXE as an applet | Next

### 4.3. Integrating the applet with your web application

#### 4.3.1. Dynamically generating an HTML page referencing the applet

A Web application typically consists of a front end communicating with a Servlet, PHP, ASP, CGI, etc, back end. The front end which runs in the Web browser generally consists in a mix of HTML and JavaScript. The code of the front end is dynamically generated by the back end in response to the preceding interactions with the user. Therefore, integrating the applet with a Web application generally means: teach the back end to dynamically generate a page referencing the applet.

In the above example, running:

    ./deploywebstart -applet xxe -index

- copies and signs the `.jar` files comprising the code of the applet;

- generates `xxe.jnlp`, an applet deployment descriptor;

- generates a sample `index.html` file, which can be used to quickly test that the applet works.

The signed `.jar` files and the `xxe.jnlp` files are expected to be used as is by your web application. Just moves these files to the actual deployment directory (which is the directory from which the Web browser will download the applet code). These files needs to be regenerated only when you'll upgrade XMLmind XML Editor.

The situation is different for the `index.html` file, which is not meant for production use. Instead, use the applet element contained in this file as a template for the applet element which will be dynamically generated by your back end:

    <applet name="XXE" id="XXE" mayscript
      code="com.xmlmind.xmleditapp.applet.Applet"
      width="100%" height="600">
      <param name="jnlp_href" value="xxe.jnlp">
      <param name="appClass" value="com.xmlmind.xmleditapp.app.Application">
      <param name="separate_jvm" value="true">
      <param name="classloader_cache" value="false">
      Sorry but XMLmind XML Editor requires the Java<sup>TM</sup> Plug-In
      version 1.6.0_10 and above in order to run.
    </applet>

For production use, you'll prefer to use a more elaborate way to deploy XXE as an applet:

    ./deploywebstart -indexjars -packjars -jsapplet xxe -index

Refer to Section 3.1, “The deploywebstart command-line tool” to learn about the `-indexjars`, `-packjars` and `-jsapplet` options.

In production, instead of generating an applet element, your back end can generate some code similar to the one generated by `deploywebstart` using the `-jsapplet` option:

        <script type="text/javascript"
                src="http://java.com/js/deployJava.js"></script>
        <script type="text/javascript">
    //<![CDATA[

          var attributes = {name:'XXE', id:'XXE', mayscript:true,
                            code:'com.xmlmind.xmleditapp.applet.Applet',
                            width:'100%', height:'600'};
          var parameters = {jnlp_href:'xxe.jnlp',
                            appClass:'com.xmlmind.xmleditapp.app.Application',
                            separate_jvm:true, classloader_cache:false};
          deployJava.runApplet(attributes, parameters, '1.6.0_10');

    //]]>
        </script>

#### 4.3.2. The four different kinds of applet

In the above code snippets, `jnlp_href`, `separate_jvm`, `classloader_cache` are system parameters documented in Development and Deployment Of Java™ Web Apps (Applets and Java Web Start Applications) for JavaSE 6u10.

Parameter ``appClass`` is specific to the XMLmind XML Editor applet. The value of this parameter is the fully qualified class name of the application deployed as an applet.

The value of this parameter is generally specified using the `-applet` or `-jsapplet` option of the `deploywebstart` command-line utility:

Option Value | Class Name
--- | ---
`viewer` | `com.xmlmind.xmleditapp.applet.ViewerApp`
`editor1` | `com.xmlmind.xmleditapp.applet.Editor1App`
`editor2` | `com.xmlmind.xmleditapp.applet.Editor2App`
`xxe` | `com.xmlmind.xmleditapp.app.Application`

There are four different applications which can be deployed as an applet. Each application is designed to solve a different problem. Each application has a different GUI:

viewer

  A document viewer having no user interface at all, except a right-click popup menu.

  In order to open a document in `viewer`, the integrator needs to wrap the corresponding command-line option in some applet parameters or to script the applet.

editor1

  A single document, single view, document editor designed to be part of an HTML form.

  This editor has no menu bar and has no New, Open, Save tool bar buttons.

  In order to create a new document using `editor1`, the integrator needs to wrap the `-new` command-line option in some applet parameters or to script the applet.

  In order to open a document in `editor1`, the integrator needs to wrap the corresponding command-line option in some applet parameters or to script the applet.

  In order to save the document edited in `editor1`, the integrator needs to make the applet part of an HTML form and to script it as follows:

  1. Query the applet for the XML source of the document being edited.

  2. Dynamically add to the form a `hidden` field containing this XML source.

  3. Submit the form.

editor2

  A single document, single view, document editor designed to be integrated with a server supporting WebDAV, FTP, FTPS or SFTP (in fact, any kind of storage for which a virtual drive plug-in is available).

  Same user interface as `editor1`, expect that `editor2` has a Save tool bar button and fully supports Save preferences.

xxe

  Full XMLmind XML Editor.

  Same user interface as the desktop application, except that it has no File → Quit menu item.

  This is an alternative to deploying XMLmind XML Editor using Java™ Web Start.

Note that despite the fact the above applications have vastly different user interfaces, it is still XMLmind XML Editor. That is, all the above applications support the same user preferences and the same add-ons as the desktop application.

#### 4.3.3. Applet parameters

In addition to the `appClass` parameter described in Section 4.3.2, “The four different kinds of applet”, the applet has up to 100 `argument`N`` parameters: `argument0`, `argument1`, `argument2`, ..., `argument99`. These parameters are used to wrap the command-line arguments supported by the desktop application.

The command-line arguments of XMLmind XML Editor are documented in Appendix A, Command line options in XMLmind XML Editor - Online Help.

The user preference keys and values of XMLmind XML Editor are documented in Section 5, “The "Preferences" dialog box” in XMLmind XML Editor - Online Help.

Example 6.1. `-applet viewer` example: open a document stored on an HTTP server

    <applet ...>
      <param name="appClass" value="com.xmlmind.xmleditapp.applet.ViewerApp">
      <param name="argument0"
             value="http://www.xmlmind.com/xmleditor/_distrib/doc/user/userguide.xml">
      ...
    </applet>

Example 6.2. Same example as above, but force the value of the `defaultFontSize` user preference in order to use a larger font to display the document

    <applet ...>
      <param name="appClass" value="com.xmlmind.xmleditapp.applet.ViewerApp">
      <param name="argument0" value="-putpref">
      <param name="argument1" value="defaultFontSize">
      <param name="argument2" value="14">
      <param name="argument3"
             value="http://www.xmlmind.com/xmleditor/_distrib/doc/user/userguide.xml">
      ...
    </applet>

Example 6.3. `-applet editor1` example: create a new DocBook article

    <applet ...>
      <param name="appClass" value="com.xmlmind.xmleditapp.applet.Editor1App">
      <param name="argument0" value="-new">
      <param name="argument1" value="docbook">
      <param name="argument2" value="article">
      <param name="argument3" value="-">
      ...
    </applet>

Example 6.4. `-jsapplet editor2` example: open a document stored on a WebDAV server requiring the user to authenticate himself

    <script type="text/javascript">
      ...
      var parameters = {
        appClass:'com.xmlmind.xmleditapp.applet.Editor2App',
        argument0:'-auth',
        argument1:'CgpEb2N1bWVudCBTdG9yZQoKanZpY3RvcmlhCnNlY3JldA==',
        argument2:'http://www.acme.com/dav/report.xml',
        ...
      };
      ...
    </script>

#### 4.3.4. Applet scripting

Applet scripting means to use JavaScript™ code to invoke some methods of the applet.

Note that you cannot safely invoke any method of the applet. You can only invoke the applet methods which have been specially designed in order to be scripted in JavaScript. Such methods are:

void addAuthorization(String `info`), void addAuthorization(String `host`, int `port`, String `prompt`, String `scheme`, String `username`, String `password`)

  Add specified non-interactive authentication credentials.

boolean newDocument(String `configName`, String `templateName`, String `saveURI`, boolean `createSaveFile`), boolean newDocument(String `templateURI`, String `saveURI`, boolean `createSaveFile`), boolean newDocument(String `template`, String `saveURI`), boolean newDocumentFromTemplate(String `template`, String `saveURI`, boolean `createSaveState`)

  Create a new document.

boolean openDocument(String `docURI`, boolean `readOnly`), boolean openDocument(String doc, String `docURI`, boolean `readOnly`), boolean openDocument(String doc, String `docURI`, boolean `readOnly`, boolean `createSaveState`)

  Opens specified document.

boolean isSaveNeeded(String `docURI`)

  Tests whether specified document needs to be saved. Example of use:

      window.onbeforeunload = function() {
          var xxe = document.XXE;
          if (xxe.isSaveNeeded(null)) {
              return "You have not clicked the \"Submit\" button.";
          }
      }

boolean unsetSaveNeeded(String `docURI`)

  Resets the state of specified document to "Save Not Needed". Except for applets such as Editor1, explicitly invoking this method is almost never needed.

boolean canCompareRevisions(String `originalDocURI`, String `revisedDocURI`)

  Tests whether specified documents can be compared using the Compare tool. Two documents can be compared if:

  - These documents are two revisions of the same initial document for which Tools → Changes → Activate Change Detection has been turned on.

  - Either a document has been opened in read-only mode or it does not need to be saved to disk (or Save As).

boolean compareRevisions(String `originalDocURI`, String `revisedDocURI`, boolean `verticalSplit`)

  Compare specified documents using the Compare tool.

  Note that the Compare tool is available only in the "`xxe`" applet because it's the only applet which can open multiple documents at the same time.

String checkValidity(String `docURI`)

  Checks the validity of specified document.

boolean closeDocument(String `docURI`, boolean `discardChanges`)

  Closes specified opened document.

String listDocuments()

  Returns the list of the URIs of currently opened documents.

String getActiveDocument()

  Returns the URI of the current ``active'' document.

boolean setActiveDocument(String `docURI`)

  Changes the current ``active'' document to specified opened document.

String getDocumentContents(String `docURI`, String `attachmentDir`)

  Returns the XML contents of specified opened document.

String listDocumentResources(String `docURI`, boolean `attachmentsOnly`)

  Returns the list of the URIs of the resources (typically graphic files) referenced in specified opened document.

String getDocumentAttachment(String `docURI`, String `attachmentURI`)

  Returns the contents of specified attachment encoded in base-64.

The reference manual of these methods is found in Class Applet.

Example 6.5. The online demo of `editor1`.

This instance of `editor1` is made part of an HTML form called `DemoForm`:

    <form method="POST" enctype="application/x-www-form-urlencoded"
          action="http://127.0.0.1:8080/applet_demo/echo"
          name="DemoForm" onsubmit="return onSubmitForm();" target="_blank">
      <input type="hidden" name="documentURI" value="" />
      <input type="hidden" name="xmlSource" value="" />
      <input type="hidden" name="attachmentCount" value="0" />

      ...

      <script type="text/javascript">
        var attributes = {name:'XXE', id:'XXE', mayscript:true,
                          code:'com.xmlmind.xmleditapp.applet.Applet',
                          width:'100%', height:'600'};
        var parameters = {jnlp_href:'xxe.jnlp',
                         appClass:'com.xmlmind.xmleditapp.applet.Editor1App',
                         separate_jvm:true, classloader_cache:false,
                         argument0:'-new',
                         argument1:'DocBook v5+/5.0',
                         argument2:'article',
                         argument3:'Untitled.xml'};
        deployJava.runApplet(attributes, parameters, '1.6.0_10');
      </script>
    </form>

| The content of the form is posted to a Servlet called `applet_demo`. In this demo, we use `enctype="application/x-www-form-urlencoded"`. In production, we would use `enctype="multipart/form-data"` (even if the form does not contain any file upload control) because this would be more efficient.

The `applet_demo` servlet expects the following query arguments:

`documentURI`

  Optional: the URI of the document.

`xmlSource`

  Required: contains the XML source of the document. The value of this field is a string which starts with `<?xml version="1.0" encoding="UTF-8"?>`.

`attachmentCount`

  Required: positive integer which specifies the number of `attachmentName`I``/`attachmentDataI` field pairs. See below.

`attachmentName0-`N``, `attachmentData0-`N``

  Optional: `attachmentName`I`` contains the absolute "`file:`" URI of the attachment. `attachmentData`I`` contains the base-64 encoded data of the attachment.

| Initially, the instance of `editor1` contains a new DocBook 5 article. The URI of this new article is `Untitled.xml` resolved against the document base of the demo, which gives: `http://www.xmlmind.com/xmleditor/_applet/Untitled.xml`.

The JavaScript function `onSubmitForm()` is implemented as follows:

    function onSubmitForm() {
        ...
        var demoForm = document.DemoForm;
        var xxe = document.XXE;

        demoForm.documentURI.value = xxe.getActiveDocument();
        ...

        demoForm.xmlSource.value = xxe.getDocumentContents(null, null);
        ...

        var attachments = xxe.listDocumentResources(null, true);
        if (attachments != null) {
            var attachmentList = attachments.split("\n");
            var count = attachmentList.length;
            if (count > 0) {
                ...
                var j = 0;

                for (var i = 0; i < count; i += 2) {
                    var name = attachmentList[i];

                    var data = xxe.getDocumentAttachment(null, attachmentList[i]);
                    ...

                    var jj = j.toString();

                    var attachmentName = document.createElement("input");
                    attachmentName.type = "hidden";
                    attachmentName.name = "attachmentName" + jj;
                    attachmentName.id = "attachmentName" + jj;
                    attachmentName.value = name;

                    var attachmentData = document.createElement("input");
                    attachmentData.type = "hidden";
                    attachmentData.name = "attachmentData" + jj;
                    attachmentData.id = "attachmentData" + jj;
                    attachmentData.value = data;

                    demoForm.appendChild(attachmentName);
                    demoForm.appendChild(attachmentData);

                    ++j;
                }

                demoForm.attachmentCount.value = j;
            }
        }

        return true;
    }

| Invoke `getActiveDocument()` to give a value to the `documentURI` `hidden` form field.
| Invoke `getDocumentContents()` to give a value to the `xmlSource` `hidden` form field.

Invoke `listDocumentResources()` to list attachments.

What is called an attachment here is a document resource having an absolute "`file:`" URI.

When an author uses the applet ``normally'' to reference a local resource, the URI of this resource is necessarily specified as an absolute "`file:`" URI. The reason for this fact is that a "`file:`" URI cannot be made relative to the URI of the edited document, which is an "`http:`" URI. The applet uses this specificity to automatically detect which resources files are to be attached to the posted XML source.

| For each attachment detected by the applet, attempt to load it using `getDocumentAttachment()` and if this succeeds, add two `hidden` fields to the form. First field contains the absolute "`file:`" URI of the attachment. Second field contains the base-64 encoded contents of the attachment.
| Give a value to the `attachmentCount` `hidden` form field.

Prev | Up | Next
4.2. Testing the XXE applet, a step by step description | Home | Part II. Reference