cocoon-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From sylv...@apache.org
Subject svn commit: r327577 - in /cocoon: blocks/forms/trunk/java/org/apache/cocoon/forms/generation/ blocks/forms/trunk/java/org/apache/cocoon/forms/util/ blocks/forms/trunk/samples/ blocks/forms/trunk/samples/sql/ blocks/forms/trunk/samples/sql/flow/ blocks/...
Date Fri, 21 Oct 2005 20:59:35 GMT
Author: sylvain
Date: Fri Oct 21 13:59:14 2005
New Revision: 327577

URL: http://svn.apache.org/viewcvs?rev=327577&view=rev
Log:
Super-easy SQL/Forms integration for simple CRUD applications

Added:
    cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/util/CombiningMap.java   (with
props)
    cocoon/blocks/forms/trunk/samples/sql/
    cocoon/blocks/forms/trunk/samples/sql/flow/
    cocoon/blocks/forms/trunk/samples/sql/flow/flow.js   (with props)
    cocoon/blocks/forms/trunk/samples/sql/flow/jdbi.js   (with props)
    cocoon/blocks/forms/trunk/samples/sql/forms/
    cocoon/blocks/forms/trunk/samples/sql/forms/employee.xml   (with props)
    cocoon/blocks/forms/trunk/samples/sql/pages/
    cocoon/blocks/forms/trunk/samples/sql/pages/employee-edit.xml   (with props)
    cocoon/blocks/forms/trunk/samples/sql/pages/employee-list.xml   (with props)
    cocoon/blocks/forms/trunk/samples/sql/resources/
    cocoon/blocks/forms/trunk/samples/sql/resources/css/
    cocoon/blocks/forms/trunk/samples/sql/resources/css/style.css   (with props)
    cocoon/blocks/forms/trunk/samples/sql/resources/forms-styling.xsl   (with props)
    cocoon/blocks/forms/trunk/samples/sql/resources/img/
    cocoon/blocks/forms/trunk/samples/sql/resources/img/background.png   (with props)
    cocoon/blocks/forms/trunk/samples/sql/resources/img/button-background.gif   (with props)
    cocoon/blocks/forms/trunk/samples/sql/resources/img/mac-add.png   (with props)
    cocoon/blocks/forms/trunk/samples/sql/resources/img/mac-delete.png   (with props)
    cocoon/blocks/forms/trunk/samples/sql/resources/page-styling.xsl   (with props)
    cocoon/blocks/forms/trunk/samples/sql/selection-list.xml   (with props)
    cocoon/blocks/forms/trunk/samples/sql/sitemap.xmap   (with props)
    cocoon/trunk/lib/optional/jdbi-1.3.1.jar   (with props)
Modified:
    cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/generation/JXMacrosHelper.java
    cocoon/blocks/forms/trunk/samples/welcome.xml
    cocoon/trunk/lib/jars.xml

Modified: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/generation/JXMacrosHelper.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/generation/JXMacrosHelper.java?rev=327577&r1=327576&r2=327577&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/generation/JXMacrosHelper.java
(original)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/generation/JXMacrosHelper.java
Fri Oct 21 13:59:14 2005
@@ -140,14 +140,18 @@
     
     protected boolean pushWidget(String path, boolean unused) throws SAXException {
         Widget parent = peekWidget();
-        // Is there an updated widget at a higher level in the template?
-        boolean inUpdatedTemplate = ((Boolean)widgetStack.peek(1)).booleanValue();
+        if (path == null || path.length() == 0) {
+            throw new FormsRuntimeException("Missing 'id' attribute on template instruction");
+        }
         Widget widget = parent.lookupWidget(path);
         if (widget == null) {
             throw new FormsRuntimeException(parent + " has no child named '" + path + "'",
parent.getLocation());
         }
 
         String id = widget.getFullName();
+        // Is there an updated widget at a higher level in the template?
+        boolean inUpdatedTemplate = ((Boolean)widgetStack.peek(1)).booleanValue();
+
         boolean display;
 
         if (ajaxRequest) {

Added: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/util/CombiningMap.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/util/CombiningMap.java?rev=327577&view=auto
==============================================================================
--- cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/util/CombiningMap.java (added)
+++ cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/util/CombiningMap.java Fri Oct
21 13:59:14 2005
@@ -0,0 +1,176 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cocoon.forms.util;
+
+import java.util.AbstractMap;
+import java.util.AbstractSet;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+/**
+ * A read-only implementation of <code>Map</code> that combines several other
maps.
+ * 
+ * @version $Id$
+ */
+public class CombiningMap extends AbstractMap {
+
+    private List maps = new ArrayList();
+    private boolean locked = false;
+
+    /**
+     * Adds a <code>Map</code> in the combined map, with the lowest lookup priority.
+     * <p>
+     * New maps cannot be added if this object was already iterated.
+     * 
+     * @param map the new map
+     * @return this object, as a convenience to write <code>combiner.add(map1).add(map2).add(map3)</code>
+     * @throw IllegalStateException if this object was already iterated.
+     */
+    public CombiningMap add(Map map) {
+        if (locked) {
+            throw new IllegalStateException("Cannot add new Maps to a CombiningMap once it
has been iterated");
+        }
+        maps.add(map);
+        
+        return this;
+    }
+    
+    public Object get(Object key) {
+        // Faster implemetation than the default in AbstractMap
+        for (int i = 0; i < maps.size(); i++) {
+            Map map = (Map)maps.get(i);
+            Object result = map.get(key);
+
+            if (result != null) {
+                return result;
+            }
+
+            if (map.containsKey(key)) {
+                return null;
+            }
+        }
+        
+        return null;
+    }
+    
+    public boolean containsKey(Object key) {
+        // Faster implemetation than the default in AbstractMap
+        for (int i = 0; i < maps.size(); i++) {
+            Map map = (Map)maps.get(i);
+            if (map.containsKey(key)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public Set entrySet() {
+        locked = true;
+        return new CombiningEntrySet();
+    }
+
+    private class CombiningEntrySet extends AbstractSet {
+
+        public Iterator iterator() {
+            return new CombiningIterator();
+        }
+
+        /**
+         * Super inefficient way, but this implementation is meant to be super-lightweight
+         * and efficient at iterations.
+         */
+        public int size() {
+           
+            int size = 0;
+            Iterator iter = iterator();
+            while (iter.hasNext()) {
+                size++;
+                iter.next();
+            }
+            return size;
+        }
+    }
+    
+    private class CombiningIterator implements Iterator {
+        
+        private int index;
+        private Iterator delegate;
+        private Map.Entry next;
+
+        public CombiningIterator() {
+            // Initialize the first result
+            if (!maps.isEmpty()) {
+                delegate = ((Map)maps.get(0)).entrySet().iterator();
+                if (delegate.hasNext()) {
+                    next = (Map.Entry)delegate.next();
+                }
+            }
+            
+        }
+        public boolean hasNext() {
+            return next != null;
+        }
+
+        public Object next() {
+            if (next == null) {
+                throw new NoSuchElementException();
+            }
+            Object result = next;
+            fetchNext();
+            return result;
+        }
+
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+        
+        private void fetchNext() {
+            boolean skip;
+            do {
+                // Get an iterator that has more values
+                while (delegate != null && !delegate.hasNext()) {
+                    // Ended iteration on the previous map
+                    index++;
+                    if (index < maps.size()) {
+                        delegate = ((Map)maps.get(index)).entrySet().iterator();
+                    } else {
+                        // Iteration finished
+                        next = null;
+                        delegate = null;
+                        return;
+                    }
+                }
+                
+                // Get the next entry
+                next = (Map.Entry)delegate.next();
+                
+                // Skip it if its key doesn't exist in the previous Maps
+                Object key = next.getKey();
+                skip = false;
+                for (int i = 0; i < index-1; i++) {
+                    if (((Map)maps.get(i)).containsKey(key)) {
+                        skip = true;
+                        continue;
+                    }
+                }
+            } while(skip);
+        }
+    }
+}

Propchange: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/util/CombiningMap.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/blocks/forms/trunk/java/org/apache/cocoon/forms/util/CombiningMap.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: cocoon/blocks/forms/trunk/samples/sql/flow/flow.js
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/samples/sql/flow/flow.js?rev=327577&view=auto
==============================================================================
--- cocoon/blocks/forms/trunk/samples/sql/flow/flow.js (added)
+++ cocoon/blocks/forms/trunk/samples/sql/flow/flow.js Fri Oct 21 13:59:14 2005
@@ -0,0 +1,136 @@
+cocoon.load("resource://org/apache/cocoon/forms/flow/javascript/Form.js");
+cocoon.load("flow/jdbi.js");
+importClass(org.apache.cocoon.forms.formmodel.WidgetState);
+
+// Add asMap() and asList() methods to Form as a syntactic convenience
+Form.prototype.asMap = function(widget) {
+    if (!widget) widget = this.form;
+    return new org.apache.cocoon.forms.util.ContainerWidgetAsMap(widget);
+}
+
+Form.prototype.asList = function(repeater) {
+    return new org.apache.cocoon.forms.util.RepeaterAsList(repeater);
+}
+
+// The DAO object for our application
+var dao = function() {};
+
+// The database interface for our DAO
+dao.dbi = new JDBI("personnel");
+
+// Factory for new IDs
+dao.newId = function(table, column) {
+    // WARNING: very dummy approach what can produce duplicate entries under load
+    //     --> use another way in production (sequences, high/low generator, etc)
+    var id = dao.dbi.first("select max(id)+1 as new_id from " + table).get("new_id");
+    if (id == null) id = new java.lang.Integer(1);
+    return id;
+}
+
+// Get the contents of a table as a selectionList
+function selection_list() {
+    var table = dao[cocoon.parameters.table];
+    if (!table) throw "No table named " + table;
+    cocoon.sendPage("selection-list.xml", { items: table.selectionList() });
+}
+
+//-------------------------------------------------------------------------------------------------
+
+dao.employee = function() {};
+
+dao.employee.get = function(id) {
+    return dao.dbi.first("select * from employee where id = ?", [id]);
+};
+    
+dao.employee.getAll = function() {
+    return dao.dbi.query("select * from employee order by name");
+};
+
+dao.employee.insert = function(employee) {
+    return dao.dbi.execute("insert into employee ( id,  department_id,  name,  description)
" +
+                                        " values (:id, :department_id, :name, :description)",
employee);
+};
+    
+dao.employee.update = function(employee) {
+    return dao.dbi.execute("update employee set department_id = :department_id, name = :name,
" +
+        "description = :description where id = :id", employee);
+};
+
+// Deletion is named "remove" as "delete" is a JS keyword   
+dao.employee.remove = function(id) {
+    return dao.dbi.execute("delete from employee where id = ?", [id]);
+};
+    
+// Above where the functions that exist on all DAOs. You can of course add specialized functions
if needed.
+
+function do_list_employees() {
+    var list = dao.employee.getAll();
+    // Call the view, giving it the list and also the dao to get department names
+    cocoon.sendPage("employee-list.html", { employees: list, dao: dao });
+}
+
+function do_edit_employee() {
+    var id = cocoon.request.getParameter("id");
+    var form = new Form("forms/employee.xml");
+    
+    // Create a Map view of the form, that will be used with JDBI
+    var formMap = form.asMap();
+    
+    if (id != null) {
+        // Get the employee as a Map
+        var employee = dao.employee.get(id);
+        if (!employee) {
+            // Should better display a dialog here
+            throw "There is no customer with id " + id;
+        }
+        
+        // Fill the form with the Map returned by JDBI.
+        // No binding file, no Java object, no nothing! Cool, isn't it?
+        //
+        // This is possible because:
+        // - both the JDBC ResultSet and the form widgets are represented as Maps and Lists
+        // - form widgets and database columns have the same name.
+        formMap.putAll(employee);
+    }
+
+    // Show the form
+    form.showForm("viewform-employee-edit.html");
+
+    if (form.isValid) {
+        // User has not pressed "cancel": insert or update employee
+        if (id == null) {
+            id = dao.newId("employee");
+            
+            // Combine form data and the newly created id in a Map
+            var data = JDBI.combine({id: id}, formMap);
+            
+            // And insert the employee.
+            // Again, no binding file, no Java object, no nothing! Cool, isn't it?
+            dao.employee.insert(data);
+        } else {
+            // Use a shorter notation now
+            dao.employee.update(JDBI.combine({id: id}, formMap));
+        }
+    }
+    
+    // Return to the list page
+    cocoon.redirectTo("do_list_employees");
+}
+
+function do_delete_employee() {
+    dao.employee.remove(cocoon.request.getParameter("id"));
+
+    // Return to the list page
+    cocoon.redirectTo("do_list_employees");
+}
+
+//-------------------------------------------------------------------------------------------------
+dao.department = function() {};
+
+dao.department.get = function(id) {
+    return dao.dbi.first("select * from department where id = ?", [id]);
+}
+
+dao.department.selectionList = function() {
+    return dao.dbi.query("select id as value, name as label from department order by name");
+}

Propchange: cocoon/blocks/forms/trunk/samples/sql/flow/flow.js
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/blocks/forms/trunk/samples/sql/flow/flow.js
------------------------------------------------------------------------------
    svn:keywords = Id

Added: cocoon/blocks/forms/trunk/samples/sql/flow/jdbi.js
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/samples/sql/flow/jdbi.js?rev=327577&view=auto
==============================================================================
--- cocoon/blocks/forms/trunk/samples/sql/flow/jdbi.js (added)
+++ cocoon/blocks/forms/trunk/samples/sql/flow/jdbi.js Fri Oct 21 13:59:14 2005
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * A JavaScript wrapper for the JDBI library (http://jdbi.codehaus.org)
+ *
+ * @version $Id$
+ */
+
+function JDBI(datasource) {
+    var selector = cocoon.getComponent(Packages.org.apache.avalon.excalibur.datasource.DataSourceComponent.ROLE
+ "Selector");
+    var datasource = selector.select(datasource);
+    // Wrap datasource as a JDBI ConnectionFactory.
+    this.dbi = new Packages.org.skife.jdbi.DBI(function() { return datasource.getConnection()
});
+
+    // Plug a statement locator that will use Cocoon's source resolver
+    var loadFunc = function(name) {
+            var resolver = cocoon.getComponent(Packages.org.apache.excalibur.source.SourceResolver.ROLE);
+            var src = resolver.resolveURI(name);
+            try {
+                if (!src.exists()) return null;
+                var result = Packages.org.apache.commons.io.IOUtils.toString(src.getInputStream());
+            } finally {
+                resolver.release(src);
+            }
+            return result;
+        };
+    this.dbi.setStatementLocator(loadFunc);
+}
+
+/**
+ * Convert a variable number of arguments to a Map. If there are several arguments, they
+ * are individually converted to a Map and combined using CombiningMap.
+ * FIXME: should be moved to a more efficient helper class
+ */
+JDBI.combine = function() {
+    if (arguments.length == 0) {
+        return java.util.Collections.EMPTY_MAP;
+    } else if (arguments.length == 1) {
+        return JDBI._toMap(arguments[1]);
+    } else {
+        var result = new Packages.org.apache.cocoon.forms.util.CombiningMap();
+        for (var i = 0; i < arguments.length; i++) {
+            result.add(JDBI._toMap(arguments[i]))
+        }
+        return result;
+    }
+}
+
+JDBI._toMap = function(obj) {
+    // FIXME: is there a better way to test "instanceof" a java class?
+    var mapClass = java.lang.Class.forName("java.util.Map");
+    if (mapClass.isInstance(obj)) {
+        return obj;
+    }
+    var result = new java.util.HashMap();
+    for (var prop in obj) {
+        result.put(prop, obj[prop]);
+    }
+    return result;
+}
+
+JDBI.prototype.open = function() {
+	return this.dbi.open();
+}
+
+/**
+ * Registers one or more named statements. If <code>statement</code> is given,
+ * then a single statement is registered. Otherwise, <code>name</code> is considered
+ * as an object of which each property defines a statement.
+ */
+JDBI.prototype.name = function(name, statement) {
+    if (statement) {
+        this.dbi.name(name, statement);
+    } else {
+        // Assume it's a mapping
+        for (var i in name) {
+            this.dbi.name(i, name[i]);
+        }
+    }
+}
+
+JDBI.prototype.__do = function(name, statement, args) {
+	var handle = this.dbi.open();
+	try {
+		var results = args ? handle[name](statement, args) : handle[name](statement);
+	} finally {
+		handle.close();
+	}
+	return results;
+}
+
+JDBI.prototype.query = function(statement, args) {
+	return this.__do("query", statement, args);
+}
+
+JDBI.prototype.first = function(statement, args) {
+	return this.__do("first", statement, args);
+}
+
+JDBI.prototype.execute = function(statement, args) {
+	return this.__do("execute", statement, args);
+}
+
+JDBI.prototype.update = function(statement, args) {
+	return this.__do("update", statement, args);
+}

Propchange: cocoon/blocks/forms/trunk/samples/sql/flow/jdbi.js
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/blocks/forms/trunk/samples/sql/flow/jdbi.js
------------------------------------------------------------------------------
    svn:keywords = Id

Added: cocoon/blocks/forms/trunk/samples/sql/forms/employee.xml
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/samples/sql/forms/employee.xml?rev=327577&view=auto
==============================================================================
--- cocoon/blocks/forms/trunk/samples/sql/forms/employee.xml (added)
+++ cocoon/blocks/forms/trunk/samples/sql/forms/employee.xml Fri Oct 21 13:59:14 2005
@@ -0,0 +1,25 @@
+<fd:form xmlns:fd="http://apache.org/cocoon/forms/1.0#definition">
+  <fd:widgets>
+    <fd:field id="name" required="true">
+      <fd:datatype base="string"/>
+    </fd:field>
+
+    <fd:field id="description">
+      <fd:datatype base="string"/>
+    </fd:field>
+
+    <fd:field id="department_id" required="true">
+      <fd:datatype base="integer"/>
+      <fd:selection-list src="cocoon:/selection-list/department"/>
+    </fd:field>
+
+    <fd:submit id="ok">
+      <fd:label>Ok</fd:label>
+    </fd:submit>
+
+    <fd:submit id="cancel" validate="false">
+      <fd:label>Cancel</fd:label>
+    </fd:submit>
+
+  </fd:widgets>
+</fd:form>
\ No newline at end of file

Propchange: cocoon/blocks/forms/trunk/samples/sql/forms/employee.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/blocks/forms/trunk/samples/sql/forms/employee.xml
------------------------------------------------------------------------------
    svn:keywords = Id

Added: cocoon/blocks/forms/trunk/samples/sql/pages/employee-edit.xml
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/samples/sql/pages/employee-edit.xml?rev=327577&view=auto
==============================================================================
--- cocoon/blocks/forms/trunk/samples/sql/pages/employee-edit.xml (added)
+++ cocoon/blocks/forms/trunk/samples/sql/pages/employee-edit.xml Fri Oct 21 13:59:14 2005
@@ -0,0 +1,26 @@
+<html xmlns:ft="http://apache.org/cocoon/forms/1.0#template"
+      xmlns:fi="http://apache.org/cocoon/forms/1.0#instance"
+      xmlns:jx="http://apache.org/cocoon/templates/jx/1.0">
+
+<jx:import uri="resource://org/apache/cocoon/forms/generation/jx-macros.xml"/>
+<head>
+  <title>Employee sheet</title>
+</head>
+<body>
+  <ft:form-template action="continue" method="POST" ajax="true">
+    <ft:continuation-id/>
+    
+    <p>
+      Name: <ft:widget id="name" fi:size="40"/> Department: <ft:widget id="department_id"/>
+    </p>
+    <p>
+      Description:<br/>
+      <ft:widget id="description" fi:type="textarea" fi:rows="10" fi:style="width: 100%"/>
+    </p>
+    <p>
+      <ft:widget id="ok"/> <ft:widget id="cancel"/>
+    </p>
+  </ft:form-template>
+</body>
+      
+</html>
\ No newline at end of file

Propchange: cocoon/blocks/forms/trunk/samples/sql/pages/employee-edit.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/blocks/forms/trunk/samples/sql/pages/employee-edit.xml
------------------------------------------------------------------------------
    svn:keywords = Id

Added: cocoon/blocks/forms/trunk/samples/sql/pages/employee-list.xml
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/samples/sql/pages/employee-list.xml?rev=327577&view=auto
==============================================================================
--- cocoon/blocks/forms/trunk/samples/sql/pages/employee-list.xml (added)
+++ cocoon/blocks/forms/trunk/samples/sql/pages/employee-list.xml Fri Oct 21 13:59:14 2005
@@ -0,0 +1,44 @@
+<html xmlns:jx="http://apache.org/cocoon/templates/jx/1.0">
+  <head>
+    <title>
+      Employees of the Cocoon company
+    </title>
+  </head>
+  <body>
+    <jx:choose>
+      <jx:when test="${employees.size() == 0}">
+        <p>There are no employees. Quick, <a href="do_edit_employee">let's hire
a new one!</a></p>
+      </jx:when>
+      <jx:otherwise>
+        <table class="data" width="100%">
+          <tr>
+            <th>Name</th>
+            <th>Description</th>
+            <th>Department</th>
+            <th />
+          </tr>
+          <jx:forEach var="person" items="${employees}">
+            <tr>
+              <td>${person.name}</td>
+              <td>${person.description}</td>
+              <td>${dao.department.get(person.department_id).name}</td>
+              <td>
+                <a href="do_edit_employee?id=${person.id}">Edit</a> &#160;
+                <a href="do_delete_employee?id=${person.id}"
+                  onclick="return confirm('Remove this employee?')">
+                  Delete
+                </a>
+              </td>
+            </tr>
+          </jx:forEach>
+        </table>
+        
+        <p>
+          <span style="float: right; font-size: 80%">Hint: try to delete all employees!</span>
+          <a class="button" href="do_edit_employee">Add a new employee</a>
+        </p>
+      </jx:otherwise>
+    </jx:choose>
+
+  </body>
+</html>
\ No newline at end of file

Propchange: cocoon/blocks/forms/trunk/samples/sql/pages/employee-list.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/blocks/forms/trunk/samples/sql/pages/employee-list.xml
------------------------------------------------------------------------------
    svn:keywords = Id

Added: cocoon/blocks/forms/trunk/samples/sql/resources/css/style.css
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/samples/sql/resources/css/style.css?rev=327577&view=auto
==============================================================================
--- cocoon/blocks/forms/trunk/samples/sql/resources/css/style.css (added)
+++ cocoon/blocks/forms/trunk/samples/sql/resources/css/style.css Fri Oct 21 13:59:14 2005
@@ -0,0 +1,57 @@
+* {
+	font-family: Verdana, sans-serif;
+	font-size: 12px;
+}
+body {
+	background: #fff url(../img/background.png) repeat-x;
+	text-align: center;
+}
+
+div.title {
+	font-size: 20px;
+	font-weight: bold;
+	text-align: center;
+	margin-top: 20px;
+	margin-bottom: 20px;
+	
+}
+
+div.content {
+	margin-left:100px;
+	margin-right: 100px;
+	padding-top: 20px;
+	text-align: left;
+}
+
+input[type="text"], input[type="password"], textarea {
+  border: 1px solid #808080;
+}
+
+input[type="submit"], .button {
+	height: 2em;
+ 	border: 1px solid #808080;
+	background-image: url(../img/button-background.gif);
+	background-repeat: repeat-x;
+}
+
+a.button {
+	/*display: inline-block;*/
+	/* top right bottom left */
+	padding: 2px 5px 2px 5px;
+	text-decoration: none;
+	color: black;
+}
+
+table.data {
+	border-collapse: collapse;
+	border: 1px dotted #808080;
+}
+table.data th {
+	padding: 0.3em;
+	border-bottom: 1px solid #808080;
+}
+table.data td {
+	padding: 0.3em;
+	border-bottom: 1px dotted #808080;
+}
+

Propchange: cocoon/blocks/forms/trunk/samples/sql/resources/css/style.css
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/blocks/forms/trunk/samples/sql/resources/css/style.css
------------------------------------------------------------------------------
    svn:keywords = Id

Added: cocoon/blocks/forms/trunk/samples/sql/resources/forms-styling.xsl
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/samples/sql/resources/forms-styling.xsl?rev=327577&view=auto
==============================================================================
--- cocoon/blocks/forms/trunk/samples/sql/resources/forms-styling.xsl (added)
+++ cocoon/blocks/forms/trunk/samples/sql/resources/forms-styling.xsl Fri Oct 21 13:59:14
2005
@@ -0,0 +1,50 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+  <!--+ Include styling stylesheets, one for the widgets, the other one for the
+      | page. As 'forms-advanced-field-styling.xsl' is a specialization of
+      | 'forms-field-styling.xsl' the latter one is imported there. If you don't
+      | want advanced styling of widgets, change it here!
+      | See xsl:include as composition and xsl:import as extension/inheritance.
+      +-->
+  <xsl:include href="resource://org/apache/cocoon/forms/resources/forms-page-styling.xsl"/>
+  <xsl:include href="resource://org/apache/cocoon/forms/resources/forms-advanced-field-styling.xsl"/>
+
+  <!-- Location of the resources directory, where JS libs and icons are stored -->
+  <xsl:param name="resources-uri">resources</xsl:param>
+  
+  <xsl:template match="head">
+    <head>
+      <xsl:apply-templates/>
+      <xsl:apply-templates select="." mode="forms-page"/>
+      <xsl:apply-templates select="." mode="forms-field"/>
+    </head>
+  </xsl:template>
+
+  <xsl:template match="body">
+    <body>
+      <!--+ !!! If template with mode 'forms-page' adds text or elements
+          |        template with mode 'forms-field' can no longer add attributes!!!
+          +-->
+      <xsl:apply-templates select="." mode="forms-page"/>
+      <xsl:apply-templates select="." mode="forms-field"/>
+      <xsl:apply-templates/>
+    </body>
+  </xsl:template>
+
+</xsl:stylesheet>

Propchange: cocoon/blocks/forms/trunk/samples/sql/resources/forms-styling.xsl
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/blocks/forms/trunk/samples/sql/resources/forms-styling.xsl
------------------------------------------------------------------------------
    svn:keywords = Id

Added: cocoon/blocks/forms/trunk/samples/sql/resources/img/background.png
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/samples/sql/resources/img/background.png?rev=327577&view=auto
==============================================================================
Binary file - no diff available.

Propchange: cocoon/blocks/forms/trunk/samples/sql/resources/img/background.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Added: cocoon/blocks/forms/trunk/samples/sql/resources/img/button-background.gif
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/samples/sql/resources/img/button-background.gif?rev=327577&view=auto
==============================================================================
Binary file - no diff available.

Propchange: cocoon/blocks/forms/trunk/samples/sql/resources/img/button-background.gif
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: cocoon/blocks/forms/trunk/samples/sql/resources/img/mac-add.png
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/samples/sql/resources/img/mac-add.png?rev=327577&view=auto
==============================================================================
Binary file - no diff available.

Propchange: cocoon/blocks/forms/trunk/samples/sql/resources/img/mac-add.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Added: cocoon/blocks/forms/trunk/samples/sql/resources/img/mac-delete.png
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/samples/sql/resources/img/mac-delete.png?rev=327577&view=auto
==============================================================================
Binary file - no diff available.

Propchange: cocoon/blocks/forms/trunk/samples/sql/resources/img/mac-delete.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Added: cocoon/blocks/forms/trunk/samples/sql/resources/page-styling.xsl
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/samples/sql/resources/page-styling.xsl?rev=327577&view=auto
==============================================================================
--- cocoon/blocks/forms/trunk/samples/sql/resources/page-styling.xsl (added)
+++ cocoon/blocks/forms/trunk/samples/sql/resources/page-styling.xsl Fri Oct 21 13:59:14 2005
@@ -0,0 +1,25 @@
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+<xsl:template match="head">
+  <head>
+    <xsl:apply-templates/>
+    <link href="resources/css/style.css" type="text/css" rel="stylesheet"/>
+  </head>
+</xsl:template>
+
+<xsl:template match="body">
+  <body>
+    <xsl:apply-templates select="@*"/>
+    <div class="title"><xsl:value-of select="../head/title"/></div>
+    <div class="content">
+      <xsl:apply-templates/>
+    </div>
+  </body>
+</xsl:template>
+
+<xsl:template match="@*|node()">
+  <xsl:copy>
+    <xsl:apply-templates select="@*|node()"/>
+  </xsl:copy>
+</xsl:template>
+</xsl:stylesheet>
\ No newline at end of file

Propchange: cocoon/blocks/forms/trunk/samples/sql/resources/page-styling.xsl
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/blocks/forms/trunk/samples/sql/resources/page-styling.xsl
------------------------------------------------------------------------------
    svn:keywords = Id

Added: cocoon/blocks/forms/trunk/samples/sql/selection-list.xml
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/samples/sql/selection-list.xml?rev=327577&view=auto
==============================================================================
--- cocoon/blocks/forms/trunk/samples/sql/selection-list.xml (added)
+++ cocoon/blocks/forms/trunk/samples/sql/selection-list.xml Fri Oct 21 13:59:14 2005
@@ -0,0 +1,10 @@
+<fd:selection-list xmlns:fd="http://apache.org/cocoon/forms/1.0#definition"
+                   xmlns:jx="http://apache.org/cocoon/templates/jx/1.0">
+  <jx:forEach var="item" items="${items}">
+    <fd:item value="${item.value}">
+      <jx:if test="${item.label}">
+        <fd:label>${item.label}</fd:label>
+      </jx:if>
+    </fd:item>
+  </jx:forEach>
+</fd:selection-list>
\ No newline at end of file

Propchange: cocoon/blocks/forms/trunk/samples/sql/selection-list.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/blocks/forms/trunk/samples/sql/selection-list.xml
------------------------------------------------------------------------------
    svn:keywords = Id

Added: cocoon/blocks/forms/trunk/samples/sql/sitemap.xmap
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/samples/sql/sitemap.xmap?rev=327577&view=auto
==============================================================================
--- cocoon/blocks/forms/trunk/samples/sql/sitemap.xmap (added)
+++ cocoon/blocks/forms/trunk/samples/sql/sitemap.xmap Fri Oct 21 13:59:14 2005
@@ -0,0 +1,90 @@
+<map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
+
+<map:components>
+  <map:selectors>
+    <map:selector name="ajax-request" src="org.apache.cocoon.ajax.AjaxRequestSelector"/>
+  </map:selectors>
+  <map:transformers default="xslt">
+    <map:transformer name="browser-update" src="org.apache.cocoon.ajax.BrowserUpdateTransformer"/>
+    <map:transformer name="i18n" src="org.apache.cocoon.transformation.I18nTransformer">
+      <catalogues default="forms">
+        <catalogue id="forms" name="messages" location="resource://org/apache/cocoon/forms/system/i18n"/>
+      </catalogues>
+    </map:transformer>
+  </map:transformers>
+</map:components>
+
+<map:flow>
+  <map:script src="flow/flow.js"/>
+  <map:script src="flow/jdbi.js"/>
+</map:flow>
+
+<map:pipelines>
+  <!-- Public URLs -->
+  <map:pipeline>
+    <!-- Main page: list employees -->
+    <map:match pattern="">
+      <map:redirect-to uri="do_list_employees"/>
+    </map:match>
+
+    <map:match pattern="do_*">
+      <map:call function="do_{1}"/>
+    </map:match>
+    
+    <map:match pattern="continue">
+      <map:call continuation="{request-param:continuation-id}"/>
+    </map:match>
+
+    <!-- Static resource, read either locally or from the jars -->
+    <map:match pattern="resources/*/**">
+      <map:select type="resource-exists">
+        <map:when test="{0}">
+          <map:read src="{0}"/>
+        </map:when>
+        <map:otherwise>
+          <map:read src="resource://org/apache/cocoon/{1}/resources/{2}"/>
+        </map:otherwise>
+      </map:select>
+    </map:match>
+  </map:pipeline>
+  
+  <!-- Internal URLs -->
+  <map:pipeline internal-only="false">
+    
+    <map:match pattern="selection-list/*">
+      <map:call function="selection_list">
+        <map:parameter name="table" value="{1}"/>
+      </map:call>
+    </map:match>
+    
+    <map:match pattern="*.xml">
+      <map:generate type="jx" src="{1}.xml"/>
+      <map:serialize type="xml"/>
+    </map:match>
+    
+    <map:match pattern="viewform-*.html">
+      <map:generate type="jx" src="pages/{1}.xml"/>
+      <map:transform type="browser-update"/>
+      <map:transform type="i18n"/>
+      <map:transform src="../resources/forms-samples-styling.xsl"/>
+      <map:select type="ajax-request">
+        <map:when test="true">
+          <map:serialize type="xml"/>
+        </map:when>
+        <map:otherwise>
+          <map:transform src="resources/page-styling.xsl"/>
+          <map:serialize type="html"/>
+        </map:otherwise>
+      </map:select>
+    </map:match>
+    
+    <map:match pattern="*.html">
+      <map:generate type="jx" src="pages/{1}.xml"/>
+      <map:transform src="resources/page-styling.xsl"/>
+      <map:serialize type="html"/>
+    </map:match>
+    
+  </map:pipeline>
+</map:pipelines>
+
+</map:sitemap>
\ No newline at end of file

Propchange: cocoon/blocks/forms/trunk/samples/sql/sitemap.xmap
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/blocks/forms/trunk/samples/sql/sitemap.xmap
------------------------------------------------------------------------------
    svn:keywords = Id

Modified: cocoon/blocks/forms/trunk/samples/welcome.xml
URL: http://svn.apache.org/viewcvs/cocoon/blocks/forms/trunk/samples/welcome.xml?rev=327577&r1=327576&r2=327577&view=diff
==============================================================================
--- cocoon/blocks/forms/trunk/samples/welcome.xml (original)
+++ cocoon/blocks/forms/trunk/samples/welcome.xml Fri Oct 21 13:59:14 2005
@@ -78,9 +78,9 @@
  </group>
 
  <group name="Database access">
-   <sample name="Zero-code SQL database access" href="sqldatabase/">
-     SQL database editing without any custom Java code, using the SQLTransformer to load
-     and update data.
+   <sample name="Easy SQL database access" href="sql/">
+     SQL database query and update without any custom Java code, O/R mapping tool nor form
binding.
+     Uses flowscript, Map and List views on the forms and the database (using <a href="http://jdbi.codehaus.org">JDBI</a>).
    </sample>
  </group>
 

Modified: cocoon/trunk/lib/jars.xml
URL: http://svn.apache.org/viewcvs/cocoon/trunk/lib/jars.xml?rev=327577&r1=327576&r2=327577&view=diff
==============================================================================
--- cocoon/trunk/lib/jars.xml (original)
+++ cocoon/trunk/lib/jars.xml Fri Oct 21 13:59:14 2005
@@ -1308,6 +1308,16 @@
     <lib>optional/wsrp4j-consumer-0.3-dev.jar</lib>
     <homepage>http://ws.apache.org/wsrp4j/</homepage>
   </file>
+  
+  <file>
+    <title>JDBI</title>
+    <description>
+      Convenient access to JDBC using Maps and List.
+    </description>
+    <used-by>Forms block</used-by>
+    <lib>optional/jdbi-1.3.1.jar</lib>
+    <homepage>http://jdbi.codehaus.org/</homepage>
+  </file>
 
 </jars>
 

Added: cocoon/trunk/lib/optional/jdbi-1.3.1.jar
URL: http://svn.apache.org/viewcvs/cocoon/trunk/lib/optional/jdbi-1.3.1.jar?rev=327577&view=auto
==============================================================================
Binary file - no diff available.

Propchange: cocoon/trunk/lib/optional/jdbi-1.3.1.jar
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream



Mime
View raw message