blob: 5981979aa0c61de3e5f20dfa378d74545cae68b9 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/
/**
* CRUD operations on the "personnel" database that comes with Cocoon samples,
* showing how a few conventions, Map and List wrappers for forms and JDBC allow
* to easily connect forms and a database.
*
* @version $Id$
*/
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, true);
}
Form.prototype.asList = function(repeater) {
return new org.apache.cocoon.forms.util.RepeaterAsList(repeater, true);
}
// The DAO object for our application
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 (see dao.department below)
function selection_list() {
var table = dao[cocoon.parameters.table];
if (!table) throw "No table named " + table;
cocoon.sendPage("selection-list.xml", { items: table.selectionList() });
}
//-------------------------------------------------------------------------------------------------
// The Data Access Object for the employees table.
// Defining DAOs is not mandatory, and SQL statements can be written directly in the flow
// functions. However, separating SQL from page flow control is a good practice. DAOs also share
// a common structure that allows entity-independent flow scenarios to be written.
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");
};
// Insert a new employee in the database
// This function (and other below) accepts a variable number of arguments, which should all be
// either JS objects of Maps. They are all combined to a single Map that defines the prepared
// statement parameters.
// The order of arguments is important as first parameters "hide" the properties held by those
// that follow.
dao.employee.insert = function() {
var employee = JDBI.combine.apply(this, arguments);
return dao.dbi.execute("insert into employee ( id, department_id, name, description) " +
" values (:id, :department_id, :name, :description)", employee);
};
dao.employee.update = function() {
var employee = JDBI.combine.apply(this, arguments);
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]);
};
// Now come the employee-related flow scenarios.
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"); // Can be null for creation
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");
// And insert the employee.
// Again, no binding file, no Java object, no nothing! Cool, isn't it?
// All parameters will be combined to a single Map to feed the database.
dao.employee.insert({id: id}, formMap);
} else {
// Use a shorter notation now
dao.employee.update({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]);
}
// Return a selection-list view of the departments. This is a list of (value, label) pairs
// that is later rendered to XML by a JXTemplate.
dao.department.selectionList = function() {
return dao.dbi.query("select id as value, name as label from department order by name");
}