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 ValueClass Name
viewercom.xmlmind.xmleditapp.applet.ViewerApp
editor1com.xmlmind.xmleditapp.applet.Editor1App
editor2com.xmlmind.xmleditapp.applet.Editor2App
xxecom.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 FileQuit menu item.

This is an alternative to deploying XMLmind XML Editor using JavaWeb 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 50 argumentN parameters: argument0, argument1, argument2, ..., argument49. 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 8.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)

Create a new document.

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

Opens specified document.

boolean isSaveNeeded(String docURI)

Tests whether specified document needs to be saved.

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"1
      name="DemoForm" onsubmit="return onSubmitForm();" target="_blank">
  <input type="hidden" name="documentURI" value="" />2
  <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+',
                     argument2:'article',
                     argument3:'Untitled.xml'};3
    deployJava.runApplet(attributes, parameters, '1.6.0_10');
  </script>
</form>

1

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.

2

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 attachmentNameI/attachmentDataI field pairs. See below.

attachmentName0-N, attachmentData0-N

Optional: attachmentNameI contains the absolute "file:" URI of the attachment. attachmentDataI contains the base-64 encoded data of the attachment.

3

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();1
    ...

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

    var attachments = xxe.listDocumentResources(null, true);3
    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]);4
                ...

                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;5
        }
    }

    return true;
}

1

Invoke getActiveDocument() to give a value to the documentURI hidden form field.

2

Invoke getDocumentContents() to give a value to the xmlSource hidden form field.

3

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.

4

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.

5

Give a value to the attachmentCount hidden form field.