Apache » Cocoon »

The Apache Cocoon Project

# Cocoon Forms 1.0

- Cocoon 2.2
- Core 2.2
- Blocks 2.2
- Maven Plugins 2.2
- Subprojects

# Migration guide

# Introduction

Forms block has been recently adapted to use features that servlet services framework provides. For in-depth details of adoption process take a look at COCOON-1991 issue.

Here you'll find description of migration process which should be easy and straightforward. It is assumed that you already have proper block structure created with archetype, see Your first Cocoon application using Maven 2.

## Connecting servlets

First of all, in order to get access to the resources that Forms block makes available you need to create a connection to its servlet. Open src/main/resources/META-INF/cocoon/spring/servlet-service.xml for edition and put this configuration inside `<servlet:context>` tag:

    <servlet:connections>
      <entry key="ajax" value-ref="org.apache.cocoon.ajax.impl.servlet"/>
      <entry key="forms" value-ref="org.apache.cocoon.forms.impl.servlet"/>
    </servlet:connections>

## Correcting links and paths

You will need to perform massive find-and-replace operation multiple times. Previously, all external (available to the browser) resources were loaded with special `_cocoon/**` matcher and internal resources (like XSL files) were loaded with `resource://` scheme. Both are now considered as bad practice.
Special, global matcher cannot be easily provided in real blocks environment because it does not support concepts like block's polymorphism and makes Cocoon more monolithic. Loading resources of other block with `resource:` is also discouraged because resources location within block is not part of any block's contract. Only resources that are available with servlet: scheme are part of block's contract and should not change without significant reasoning.

Now you will see list of couple old and new paths/links. Performing normal find-and-replace operation on your block that you are migrating should be enough. Here is the list:

    resource://org/apache/cocoon/forms/flow/javascript/Form.js
    servlet:forms:/resource/internal/flow/javascript/Form.js

    resource://org/apache/cocoon/forms/generation/jx-macros.xml
    servlet:forms:/resource/internal/generation/jx-macros.xml

    resource://org/apache/cocoon/forms/system/i18n
    servlet:forms:/resource/internal/i18n

    resource://org/apache/cocoon/forms/resources/forms-page-styling.xsl
    servlet:forms:/resource/internal/xsl/forms-page-styling.xsl

    resource://org/apache/cocoon/forms/resources/forms-advanced-field-styling.xsl
    servlet:forms:/resource/internal/xsl/forms-advanced-field-styling.xsl

## forms-samples-styling.xsl

If you use forms-samples-styling.xsl for transforming your Forms into HTML code you will have to update it to newer version. Important change (apart from modified paths mentioned above) is that you should replace this fragment:

    <!-- Location of the resources directory, where JS libs and icons are stored -->
    <xsl:param name="resources-uri">resources</xsl:param>

with this one:

    <!-- Location of the resources directories, where JS libs and icons are stored -->
    <xsl:param name="dojo-resources"/>
    <xsl:param name="forms-resources"/>

## Javascript adjustments (for widgets authors)

If you happened to write custom widget you probably will need to adjust your code, also. Unfortunately, this step can be more troublesome than others and can demand from you better understanding of the changes that has been incorporated into Forms code during refactoring process. Here, the most important issues will be highlighted taking as example migration of MultiValueEditor from Cocoon's distribution.
Here is the diff:

    Index: src/main/resources/org/apache/cocoon/forms/resources/js/MultiValueEditor.js
    ===================================================================
    --- src/main/resources/org/apache/cocoon/forms/resources/js/MultiValueEditor.js	(wersja 517778)
    +++ src/main/resources/org/apache/cocoon/forms/resources/js/MultiValueEditor.js	(wersja 517779)
    @@ -39,9 +39,9 @@

             cformsIdPrefix: "id-prefix-not-set",

    -        resourcesUri: cocoon.resourcesUri, // to make this available to the template
    +        formsResourcesUri: cocoon.formsResourcesUri, // to make this available to the template

    -        templatePath: cocoon.resourcesUri + "/forms/js/templates/MultiValueEditor.html",
    +        templatePath: cocoon.formsResourcesUri + "/js/templates/MultiValueEditor.html",

             fillInTemplate: function(args, frag) {
                 cocoon.forms.MultiValueEditor.superclass.fillInTemplate(this, args, frag);

    Index: src/main/resources/org/apache/cocoon/forms/resources/js/templates/MultiValueEditor.html
    ===================================================================
    --- src/main/resources/org/apache/cocoon/forms/resources/js/templates/MultiValueEditor.html	(wersja 517778)
    +++ src/main/resources/org/apache/cocoon/forms/resources/js/templates/MultiValueEditor.html	(wersja 517779)
    @@ -9,11 +9,11 @@
             </select>
           </td>
           <td width="20px">
    -        <input dojoAttachPoint="deleteButton" type="image" src="${this.resourcesUri}/forms/img/delete.gif"/>
    +        <input dojoAttachPoint="deleteButton" type="image" src="${this.formsResourcesUri}/img/delete.gif"/>
             <br/>
    -        <input dojoAttachPoint="moveUpButton" type="image" src="${this.resourcesUri}/forms/img/move_up.gif"/>
    +        <input dojoAttachPoint="moveUpButton" type="image" src="${this.formsResourcesUri}/img/move_up.gif"/>
             <br/>
    -        <input dojoAttachPoint="moveDownButton" type="image" src="${this.resourcesUri}/forms/img/move_down.gif"/>
    +        <input dojoAttachPoint="moveDownButton" type="image" src="${this.formsResourcesUri}/img/move_down.gif"/>
             <br/>
           </td>
         </tr>

As you can see, there is no `cocoon.resourcesUri` property anymore. If you put your own widget in Forms' resource tree, simply replace `cocoon.resourcesUri` with `cocoon.formsResourcesUri`. Otherwise, introduce your own property and set it's value to `"servlet:/resource/external/yourwidget/"` or similar.
If you use Forms URI, don't forget to remove redundant `"/forms"` prefix (see example above).

Note: It has been removed because there is no universal `_cocoon/**` matcher loading resources for all blocks (including Forms); now every block is responsible on its own for loading its resources. Even more, there is no universal pattern for resources URLs because blocks can be mounted at different locations. You may think that situation is worse than it used to be but it's not the case. If you think that I suggest to learn more about servlet service framework.

If you have additional questions don't hesitate to ask for a help on user's mailing list.

## Sitemap adjustments

Obviously, you have to adjust your sitemap too to pass new parameters:

    <map:transform src="resources/forms-samples-styling.xsl">
      <map:parameter name="resources-uri" value="{request:contextPath}/_cocoon/resources"/>
    </map:transform>

should be replaced with:

    <map:transform src="resources/forms-samples-styling.xsl">
      <map:parameter name="dojo-resources" value="{servlet:ajax:/resource/external/dojo}"/>
      <map:parameter name="forms-resources" value="{servlet:forms:/resource/external/forms}"/>
    </map:transform>

Of course you may have little bit different configuration. Above fragments are mentioned for explanatory purpose.

Links with in `servlet:` scheme cannot be included in HTML code sent to the browser thus you need to perform link rewriting step just before serialization. In order to do that, you will need to add `servletLinkRewriting` transformer as shown in this example:

         <map:match pattern="*-display-pipeline.jx">
           <map:generate type="jx" src="forms/{1}_template.xml" label="content1">
             <map:parameter name="locale" value="{flow-attribute:locale}"/>
           </map:generate>
           <map:transform type="browser-update"/><!-- AJAX-style form update -->
           <map:transform type="i18n">
             <map:parameter name="locale" value="{flow-attribute:locale}"/>
           </map:transform>
           <map:call resource="simple-page2html">
             <map:parameter name="file" value="forms/{1}_template.xml"/>
           </map:call>
           <map:transform src="resources/forms-samples-styling.xsl">
             <map:parameter name="dojo-resources" value="{servlet:ajax:/resource/external/dojo}"/>
             <map:parameter name="forms-resources" value="{servlet:forms:/resource/external/forms}"/>
             <map:parameter name="dojo-debug" value="true"/><!-- set to true to turn on dojo debugging in the Browser -->
             <map:parameter name="dojo-locale" value="{flow-attr:locale}"/>
           </map:transform>
           <map:transform type="i18n">
             <map:parameter name="locale" value="{flow-attribute:locale}"/>
           </map:transform>

           <map:transform type="servletLinkRewriter"/> <!-- here is the transformation step you will need to add -->

           <map:select type="ajax-request">
             <map:when test="true"><!-- sending a partial Browser Update -->
                <map:select type="request-parameter">
                  <map:parameter name="parameter-name" value="dojo.transport"/>
                  <map:when test="iframe"><!-- sending BU via iFrameIO -->
                    <map:transform src="servlet:forms:/resource/internal/xsl/IframeTransport-bu-styling.xsl"/>
                    <map:serialize type="xhtml"/><!-- this is REALLY important -->
                  </map:when>
                  <map:otherwise><!-- sending BU via XHR -->
                    <map:serialize type="xml"/>
                  </map:otherwise>
                </map:select>
             </map:when>
             <map:otherwise><!-- sending a complete page -->
               <map:serialize type="html"/>
             </map:otherwise>
           </map:select>
         </map:match>

You should add that transformer to all pipelines that transform Forms code into HTML.

Also, this is last step of whole migration process. After performing all steps you need to rebuild your block and clear browser cache to get everything working as before refactoring and migration process.

## See also

You may also be interested with AJAX migration guide.

Errors and Improvements? If you see any errors or potential improvements in this document please help us: View, Edit or comment on the latest development version (registration required).