Requirements

Cocoon Part

Sitemap

    <map:transformer logger="sitemap.transformer.xmldb" name="xmldb" src="org.apache.cocoon.transformation.XMLDBTransformer">
      <!-- Driver class (optional). Uncomment if you want XMLDBTransformer
           to create and register XML:DB database. Keep commented out if
           database created somewhere else (for example, by XML:DB source factory)
      <driver>org.apache.xindice.client.xmldb.embed.DatabaseImpl</driver>
      -->
      <base>xmldb:xindice-embed:///db</base>
    </map:transformer>
    
    <!--#######################################################-->
    <!-- eXist's XMLDBTransformer                              -->
    <!--#######################################################-->
    <map:transformer name="xmldb" src="org.exist.cocoon.XMLDBTransformer"/>
</map:transformers>
...
<!-- Control Flow -->    
<map:flow language="javascript">
  <!-- Flow will use the javascript functions defined in the files here -->
  <map:script src="javascript/flow/test.js"/>
</map:flow>
...
        <!-- call to js functions -->
        <map:match pattern="test">
                <map:act src="xmldb:exist:///db" type="xmldb-login">
                        <map:call function="test"/>
                 </map:act>
                 <!-- no session found: display login form -->
                 <map:generate src="data/xml/login.xml" type="jx">
                 <map:parameter name="requri" value="{request:requestURI}" />
                 </map:generate>
                  <map:transform src="stylesheets/xsl/doc2html-2.xsl"/>
                 <map:serialize type="xhtml"/>
        </map:match>
...
<!-- Cforms pipelines -->
        <map:match pattern="*-display-pipeline">
                <map:generate src="cforms/template/{1}_tpl.xml"/>
                <map:transform type="forms"/>
                <map:transform type="i18n">
                        <map:parameter name="locale" value="de-DE"/>
                </map:transform>
                <map:transform src="resources/forms-samples-styling.xsl"/>
                <map:serialize/>
        </map:match>

        <map:match pattern="*-success-pipeline">
                <map:generate src="data/html/ok.html"/>
                <map:serialize type="html" />
        </map:match>

Flow

cocoon.load("resource://org/apache/cocoon/forms/flow/javascript/Form.js");

function test() {
    var form = new Form("cforms/definition/test_def.xml");
    var bindingURI = "cforms/binding/test_bind.xml";
    form.createBinding(bindingURI);
    var docBaseURI = "xmldb:exist:///db/test/";
    var docName = "test.xml";
    var document = loadDocument(docBaseURI + docName);
    form.load(document);
    form.showForm("test-display-pipeline");
    form.save(document);
    // saveDocument(document, docURI);
    saveDocumentAuth(document, "test.xml", docBaseURI, "user", "pass", "true");
    var model = form.getModel();
    var bizdata = { "username" : model.name }
    cocoon.sendPage("test-success-pipeline", bizdata);
}


/**
 * Translate source path into target path so we keep a clean source XML.
 */
function makeTargetURI(path) {
    var sfx = ".xml";
    var newSfx = "-result.xml";
    var newPath = path;
    if (path.match(/^.*\.xml$/)) {
        newPath = path.substring(0, path.length - ".xml".length);
    }
    return newPath + newSfx;
}

function loadDocument(uri) {
    var parser = null;
    var source = null;
    var resolver = null;
    try {
        parser = cocoon.getComponent(Packages.org.apache.excalibur.xml.dom.DOMParser.ROLE);
        resolver = cocoon.getComponent(Packages.org.apache.cocoon.environment.SourceResolver.ROLE);
        source = resolver.resolveURI(uri);
        var is = new Packages.org.xml.sax.InputSource(source.getInputStream());
        is.setSystemId(source.getURI());
        return parser.parseDocument(is);
    } finally {
        if (source != null)
            resolver.release(source);
        cocoon.releaseComponent(parser);
        cocoon.releaseComponent(resolver);
    }
}


function saveDocumentAuth(document, docname, dburi, user, password, overwrite) {
                // exist API http://exist.sourceforge.net/api/index.html
                // XMLUtils API http://cocoon.apache.org/2.1/apidocs/
                
                importClass(Packages.org.xmldb.api.DatabaseManager);
                importClass(Packages.org.xmldb.api.base.Collection);
                importClass(Packages.org.xmldb.api.modules.XMLResource);
                importClass(Packages.org.apache.excalibur.xml.sax.SAXParser);
        
                // Error Messages
                var _errmsg = null;
                var _errdesc = null;
                
                // set the document xml data
                var xmldata = Packages.org.apache.cocoon.xml.XMLUtils.serializeNode(document);

                // Collection (org.xmldb.api.base.Collection)
                var collection = null;
                
                // ressource (org.xmldb.api.modules.XMLResource)
                var _resource = null;           
                
                try {
                    collection = DatabaseManager.getCollection(dburi, user, password);
                    collection.setProperty("sax-document-events", "false");
                    try {
                            _resource = collection.getResource(docname);
                            if(_resource != null) {
                                    if(overwrite.equals("true")) {
                                            collection.removeResource(_resource);
                                            _resource = collection.createResource( docname, "XMLResource" );
                                            _resource.setContent(xmldata);
                                            collection.storeResource(_resource);
                                    } else {
                                            _errmsg = "Resource " + docname + " does already exist";
                                            _errdesc = "Resource " + docname + " does already exist";
                                            cocoon.log.error(_errmsg);
                                            cocoon.log.error(_errdesc);
                                    }
                            } else {
                                    _resource = collection.createResource( docname, "XMLResource" );
                                    _resource.setContent(xmldata);
                                    collection.storeResource(_resource);
                            }
                    } catch(_ex) { // XMLDBException
                            _errmsg = _ex.getMessage;
                            _errdesc = "Failed to store document" + docname;
                            cocoon.log.error(_errmsg);
                            cocoon.log.error(_errdesc);
                    }
                } catch(_e) { // XMLDBException
                    _errmsg = _e.toString();
                    _errdesc = "Failed to get collection " + dburi;
                    cocoon.log.error(_errmsg);
                    cocoon.log.error(_errdesc);
                }
}

function saveDocument(document, uri) {
    var source = null;
    var resolver = null;
    var outputStream = null;
    try {
        resolver = cocoon.getComponent(Packages.org.apache.cocoon.environment.SourceResolver.ROLE);
        source = resolver.resolveURI(uri);

        var tf = Packages.javax.xml.transform.TransformerFactory.newInstance();

        if (source instanceof Packages.org.apache.excalibur.source.ModifiableSource
            && tf.getFeature(Packages.javax.xml.transform.sax.SAXTransformerFactory.FEATURE)) {

            outputStream = source.getOutputStream();
            var transformerHandler = tf.newTransformerHandler();
            var transformer = transformerHandler.getTransformer();
            transformer.setOutputProperty(Packages.javax.xml.transform.OutputKeys.INDENT, "true");
            transformer.setOutputProperty(Packages.javax.xml.transform.OutputKeys.METHOD, "xml");
            transformerHandler.setResult(new Packages.javax.xml.transform.stream.StreamResult(outputStream));

            var streamer = new Packages.org.apache.cocoon.xml.dom.DOMStreamer(transformerHandler);
            streamer.stream(document);
        } else {
            throw new Packages.org.apache.cocoon.ProcessingException("Cannot write to source " + uri);
        }
    } finally {
        if (source != null)
            resolver.release(source);
        cocoon.releaseComponent(resolver);
        if (outputStream != null) {
            try {
                outputStream.flush();
                outputStream.close();
            } catch (error) {
                cocoon.log.error("Could not flush/close outputstream: " + error);
            }
        }
    }
}

Cforms

Definition

<?xml version="1.0" ?>
<fd:form xmlns:fd="http://apache.org/cocoon/forms/1.0#definition">
<fd:widgets>
<fd:repeater id="users" initial-size="1">
  <fd:label>Users</fd:label>
        <fd:widgets>
                <fd:output id="id">
                        <fd:datatype base="long"/>
                </fd:output>
                <fd:field id="name" required="true">
                        <fd:label>Name:</fd:label>
                        <fd:datatype base="string"/>
                        <fd:validation>
                                <fd:length min="2"/>
                        </fd:validation>
                </fd:field>

                <fd:field id="email" required="true">
                        <fd:label>Email address:</fd:label>
                        <fd:datatype base="string"/>
                        <fd:validation>
                                <fd:email/>
                        </fd:validation>
                </fd:field>
                <fd:booleanfield id="select">
                        <fd:label>Select</fd:label>
                </fd:booleanfield>
        </fd:widgets>
  <fd:validation>
     [...]
  </fd:validation>
</fd:repeater>
    <fd:repeater-action id="adduser" command="add-row" repeater="users">
      <fd:label>Add User</fd:label>
    </fd:repeater-action>
  
    <fd:repeater-action id="removeuser" command="delete-rows" repeater="users" select="select">
      <fd:label>Remove selected users</fd:label>
    </fd:repeater-action>
</fd:widgets>
</fd:form>

Template

<html xmlns:ft="http://apache.org/cocoon/forms/1.0#template" xmlns:fi="http://apache.org/cocoon/forms/1.0#instance">
  <head>
    <title>Testform</title>
  </head>
  <body>
    <h1>Test</h1>
    <ft:form-template action="#{$continuation/id}.continue" method="POST">
    <ft:widget-label id="users"/>
    <ft:repeater-size id="users"/>
        <table border="1">
          <tr>
            <th><ft:repeater-widget-label id="users" widget-id="name"/></th>
            <th><ft:repeater-widget-label id="users" widget-id="email"/></th>
            <th><ft:repeater-widget-label id="users" widget-id="select"/></th>
          </tr>
          <ft:repeater-widget id="users">
                <tr>
                        <td><ft:widget id="id"/><ft:widget id="name"/></td>
                        <td><ft:widget id="email"/></td>
                        <td><ft:widget id="select"/></td>
                </tr>
          </ft:repeater-widget>
          <tr>
            <td colspan="3">
              <ft:widget id="adduser"/>
              <ft:widget id="removeuser"/>
            </td>
          </tr>
        </table>
      <input type="submit"/>
    </ft:form-template>
  </body>
</html>

Binding

<?xml version="1.0"?>
<fb:context 
            xmlns:fb="http://apache.org/cocoon/forms/1.0#binding" 
            xmlns:fd="http://apache.org/cocoon/forms/1.0#definition" 
            path="/" >
  <!--
    - Repeater requires unique identification mechanism of the row-nodes.
    - (it is of course possible to implement other binding strategies)
    -->
  <fb:repeater id="users"
               parent-path="users"
               row-path="user">
    <fb:identity>
      <fb:value id="id" path="@id" direction="load">
        <!-- optional convertor to use for mapping the unique id -->
        <fd:convertor datatype="long" />
      </fb:value>
    </fb:identity>
    <fb:on-bind>
      <!-- executed on updates AND right after the insert -->
      <fb:javascript id="id" path="@id" direction="save">
      <!-- FIXME: Need Bugfix, this is probably NOT failsave for multi-user accesses (@id)! -->
        <fb:save-form>
          var appValue = jxpathPointer.getValue();
          if (appValue == '') {
              var user = widget;
              var form = widget.getForm();
              var users = user.lookupWidget("/users");
              var max = 0;
              for (var i=0; i &lt; users.getSize(); i++) {
                if (max &lt; users.getRow(i).lookupWidget("id").getValue() ) {
                        max = users.getRow(i).lookupWidget("id").getValue();
                }
              }
              var newId = Number(max) +1;
              jxpathPointer.setValue(newId.toFixed(0));
          }
        </fb:save-form>
      </fb:javascript>
      <fb:value id="name" path="name" />
      <fb:value id="email"     path="email"     />
    </fb:on-bind>
    <fb:on-delete-row>
      <fb:delete-node />
    </fb:on-delete-row>

    <fb:on-insert-row>
      <fb:insert-node>
        <user id="">
          <name/>
          <email/>
        </user>              
      </fb:insert-node>
    </fb:on-insert-row>
  </fb:repeater>

</fb:context>

CformsExistAndFlow (last edited 2009-09-20 23:41:38 by localhost)