click-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From med...@apache.org
Subject svn commit: r768530 [2/2] - in /incubator/click/trunk/click: ./ build/ examples/ examples/src/ examples/src/org/apache/click/examples/page/ examples/src/org/apache/click/examples/page/ajax/ examples/src/org/apache/click/examples/page/cayenne/ examples/...
Date Sat, 25 Apr 2009 13:50:30 GMT
Modified: incubator/click/trunk/click/examples/src/org/apache/click/examples/page/table/LargeDatasetDemo.java
URL: http://svn.apache.org/viewvc/incubator/click/trunk/click/examples/src/org/apache/click/examples/page/table/LargeDatasetDemo.java?rev=768530&r1=768529&r2=768530&view=diff
==============================================================================
--- incubator/click/trunk/click/examples/src/org/apache/click/examples/page/table/LargeDatasetDemo.java (original)
+++ incubator/click/trunk/click/examples/src/org/apache/click/examples/page/table/LargeDatasetDemo.java Sat Apr 25 13:50:28 2009
@@ -1,151 +1,160 @@
-/*
- * 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.
- */
-package org.apache.click.examples.page.table;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.click.control.Column;
-import org.apache.click.control.Table;
-import org.apache.click.examples.page.BorderPage;
-
-/**
- * Provides a demonstration of a Table with a huge number of rows and how to
- * lazily page through the rows using a custom List implementation.
- *
- * @author Bob Schellink
- */
-public class LargeDatasetDemo extends BorderPage {
-
-    public Table table;
-
-    public LargeDatasetDemo() {
-        table = new Table();
-
-        // Setup customers table
-        table.setClass(Table.CLASS_ITS);
-
-        Column column = new Column("name");
-        column.setWidth("140px;");
-        table.addColumn(column);
-
-        column = new Column("email");
-        column.setAutolink(true);
-        column.setWidth("230px;");
-        table.addColumn(column);
-
-        column = new Column("age");
-        column.setTextAlign("center");
-        column.setWidth("40px;");
-        table.addColumn(column);
-
-        column = new Column("holdings");
-        column.setFormat("${0,number,#,##0.00}");
-        column.setTextAlign("right");
-        column.setWidth("100px;");
-        table.addColumn(column);
-
-        table.setPageSize(5);
-    }
-
-    /**
-     * @see org.apache.click.Page#onRender()
-     */
-    public void onRender() {
-        // Create DataProvider for the specified table and total number of customers
-        DataProvider dataProvider = new DataProvider(table, getCustomerCount());
-
-        // Set the DataProvider as the Table row list. Table is now able to
-        // calculate the last row value.
-        // NOTE: If table rowList is not set, table cannot calculate the last row
-        // and invoking #getLastRow will return 0.
-        table.setRowList(dataProvider);
-
-        // Retrieve customers given the firstRow, lastRow and pageSize
-        List customers = getCustomers(table.getFirstRow(), table.getLastRow(), table.getPageSize());
-
-        // Add the customers to the table dataProvider
-        dataProvider.addAll(customers);
-    }
-
-    // ---------------------------------------------------------- Inner Classes
-
-    /**
-     * Provides a custom List implementation which returns a pre-defined size,
-     * even if the underlying amount of entries is less.
-     *
-     * The List also returns correct row for a specified index by offsetting
-     * the index against the Table's firstRow value.
-     */
-    class DataProvider extends ArrayList {
-
-        /** The DataProvider Table instance. */
-        private Table table;
-
-        /** The total number of rows of the dataProvider. */
-        private int numOfRows;
-
-        /**
-         * Create a new DataProvider instance for the given Table and total number
-         * of rows.
-         *
-         * @param table this dataProvider Table instance
-         * @param numOfRows the total number of rows of the dataProvider
-         */
-        public DataProvider(Table table, int numOfRows) {
-            this.table = table;
-            this.numOfRows = numOfRows;
-        }
-
-        /**
-         * Returns the row at the specified index, offsetted by the current
-         * table first row value.
-         *
-         * @param index the index of the row as viewed in the Table
-         * @return the the row at the specified index, offsetted by the
-         * current table first row value.
-         */
-        public Object get(final int index) {
-            int realIndex = index - table.getFirstRow();
-            return super.get(realIndex);
-        }
-
-        /**
-         * Always return the total number of rows even the number of entries
-         * are less.
-         */
-        public int size() {
-            return numOfRows;
-        }
-    }
-
-    // -------------------------------------------------------- Private Methods
-
-    private int getCustomerCount() {
-        return getCustomerService().getNumberOfCustomers();
-    }
-
-    private List getCustomers(int from, int to, int pageSize) {
-        // Below we retrieve only those customers between the from and to
-        // args. In a real application one would use an ORM or JDBC to only
-        // retrieve the needed rows
-        return getCustomerService().getCustomersForPage(from, pageSize);
-    }
-
-}
+/*
+ * 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.
+ */
+package org.apache.click.examples.page.table;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.annotation.Resource;
+
+import org.apache.click.control.Column;
+import org.apache.click.control.Table;
+import org.apache.click.examples.domain.Customer;
+import org.apache.click.examples.page.BorderPage;
+import org.apache.click.examples.service.CustomerService;
+import org.springframework.stereotype.Component;
+
+/**
+ * Provides a demonstration of a Table with a huge number of rows and how to
+ * lazily page through the rows using a custom List implementation.
+ *
+ * @author Bob Schellink
+ */
+@Component
+public class LargeDatasetDemo extends BorderPage {
+
+    public Table table;
+
+    @Resource(name="customerService")
+    private CustomerService customerService;
+
+    public LargeDatasetDemo() {
+        table = new Table();
+
+        // Setup customers table
+        table.setClass(Table.CLASS_ITS);
+
+        Column column = new Column("name");
+        column.setWidth("140px;");
+        table.addColumn(column);
+
+        column = new Column("email");
+        column.setAutolink(true);
+        column.setWidth("230px;");
+        table.addColumn(column);
+
+        column = new Column("age");
+        column.setTextAlign("center");
+        column.setWidth("40px;");
+        table.addColumn(column);
+
+        column = new Column("holdings");
+        column.setFormat("${0,number,#,##0.00}");
+        column.setTextAlign("right");
+        column.setWidth("100px;");
+        table.addColumn(column);
+
+        table.setPageSize(5);
+    }
+
+    /**
+     * @see org.apache.click.Page#onRender()
+     */
+    public void onRender() {
+        // Create DataProvider for the specified table and total number of customers
+        DataProvider dataProvider = new DataProvider(table, getCustomerCount());
+
+        // Set the DataProvider as the Table row list. Table is now able to
+        // calculate the last row value.
+        // NOTE: If table rowList is not set, table cannot calculate the last row
+        // and invoking #getLastRow will return 0.
+        table.setRowList(dataProvider);
+
+        // Retrieve customers given the firstRow, lastRow and pageSize
+        List customers = getCustomers(table.getFirstRow(), table.getLastRow(), table.getPageSize());
+
+        // Add the customers to the table dataProvider
+        dataProvider.addAll(customers);
+    }
+
+    // ---------------------------------------------------------- Inner Classes
+
+    /**
+     * Provides a custom List implementation which returns a pre-defined size,
+     * even if the underlying amount of entries is less.
+     *
+     * The List also returns correct row for a specified index by offsetting
+     * the index against the Table's firstRow value.
+     */
+    class DataProvider extends ArrayList {
+
+        /** The DataProvider Table instance. */
+        private Table table;
+
+        /** The total number of rows of the dataProvider. */
+        private int numOfRows;
+
+        /**
+         * Create a new DataProvider instance for the given Table and total number
+         * of rows.
+         *
+         * @param table this dataProvider Table instance
+         * @param numOfRows the total number of rows of the dataProvider
+         */
+        public DataProvider(Table table, int numOfRows) {
+            this.table = table;
+            this.numOfRows = numOfRows;
+        }
+
+        /**
+         * Returns the row at the specified index, offsetted by the current
+         * table first row value.
+         *
+         * @param index the index of the row as viewed in the Table
+         * @return the the row at the specified index, offsetted by the
+         * current table first row value.
+         */
+        public Object get(final int index) {
+            int realIndex = index - table.getFirstRow();
+            return super.get(realIndex);
+        }
+
+        /**
+         * Always return the total number of rows even the number of entries
+         * are less.
+         */
+        public int size() {
+            return numOfRows;
+        }
+    }
+
+    // -------------------------------------------------------- Private Methods
+
+    private int getCustomerCount() {
+        return customerService.getNumberOfCustomers();
+    }
+
+    private List<Customer> getCustomers(int from, int to, int pageSize) {
+        // Below we retrieve only those customers between the from and to
+        // args. In a real application one would use an ORM or JDBC to only
+        // retrieve the needed rows
+        return customerService.getCustomersForPage(from, pageSize);
+    }
+
+}

Modified: incubator/click/trunk/click/examples/src/org/apache/click/examples/page/table/SearchTablePage.java
URL: http://svn.apache.org/viewvc/incubator/click/trunk/click/examples/src/org/apache/click/examples/page/table/SearchTablePage.java?rev=768530&r1=768529&r2=768530&view=diff
==============================================================================
--- incubator/click/trunk/click/examples/src/org/apache/click/examples/page/table/SearchTablePage.java (original)
+++ incubator/click/trunk/click/examples/src/org/apache/click/examples/page/table/SearchTablePage.java Sat Apr 25 13:50:28 2009
@@ -21,6 +21,8 @@
 import java.io.Serializable;
 import java.util.List;
 
+import javax.annotation.Resource;
+
 import org.apache.click.control.AbstractLink;
 import org.apache.click.control.ActionLink;
 import org.apache.click.control.Column;
@@ -33,14 +35,17 @@
 import org.apache.click.examples.domain.Customer;
 import org.apache.click.examples.page.BorderPage;
 import org.apache.click.examples.page.EditCustomer;
+import org.apache.click.examples.service.CustomerService;
 import org.apache.click.extras.control.DateField;
 import org.apache.click.extras.control.LinkDecorator;
+import org.springframework.stereotype.Component;
 
 /**
  * Provides an demonstration of Table control paging.
  *
  * @author Malcolm Edgar
  */
+@Component
 public class SearchTablePage extends BorderPage implements Serializable {
 
     private static final long serialVersionUID = 1L;
@@ -53,6 +58,9 @@
     private TextField nameField = new TextField(Customer.NAME_PROPERTY);
     private DateField dateField = new DateField(Customer.DATE_JOINED_PROPERTY, "Start Date");
 
+    @Resource(name="customerService")
+    private CustomerService customerService;
+
     // ----------------------------------------------------------- Constructors
 
     public SearchTablePage() {
@@ -141,16 +149,17 @@
      */
     public boolean onDeleteClick() {
         Integer id = deleteLink.getValueInteger();
-        getCustomerService().deleteCustomer(id);
+        customerService.deleteCustomer(id);
         return true;
     }
 
     /**
      * @see org.apache.click.Page#onRender()
      */
+    @Override
     public void onRender() {
         List customers =
-            getCustomerService().getCustomers(nameField.getValue(), dateField.getDate());
+            customerService.getCustomers(nameField.getValue(), dateField.getDate());
 
         table.setRowList(customers);
     }

Modified: incubator/click/trunk/click/examples/src/org/apache/click/examples/page/table/TableDecorator.java
URL: http://svn.apache.org/viewvc/incubator/click/trunk/click/examples/src/org/apache/click/examples/page/table/TableDecorator.java?rev=768530&r1=768529&r2=768530&view=diff
==============================================================================
--- incubator/click/trunk/click/examples/src/org/apache/click/examples/page/table/TableDecorator.java (original)
+++ incubator/click/trunk/click/examples/src/org/apache/click/examples/page/table/TableDecorator.java Sat Apr 25 13:50:28 2009
@@ -20,6 +20,8 @@
 
 import java.util.List;
 
+import javax.annotation.Resource;
+
 import org.apache.click.Context;
 import org.apache.click.control.ActionLink;
 import org.apache.click.control.Column;
@@ -29,12 +31,15 @@
 import org.apache.click.examples.domain.Customer;
 import org.apache.click.examples.page.BorderPage;
 import org.apache.click.examples.page.EditCustomer;
+import org.apache.click.examples.service.CustomerService;
+import org.springframework.stereotype.Component;
 
 /**
  * Provides an demonstration of Table control paging.
  *
  * @author Malcolm Edgar
  */
+@Component
 public class TableDecorator extends BorderPage {
 
     public Table table = new Table();
@@ -44,6 +49,9 @@
     public PageLink editLink = new PageLink("edit", EditCustomer.class);
     public ActionLink deleteLink = new ActionLink("delete", this, "onDeleteClick");
 
+    @Resource(name="customerService")
+    private CustomerService customerService;
+
     // ------------------------------------------------------------ Constructor
 
     public TableDecorator() {
@@ -102,21 +110,22 @@
 
     public boolean onViewClick() {
         Integer id = viewLink.getValueInteger();
-        customerDetail = getCustomerService().getCustomerForID(id);
+        customerDetail = customerService.getCustomerForID(id);
         return true;
     }
 
     public boolean onDeleteClick() {
         Integer id = deleteLink.getValueInteger();
-        getCustomerService().deleteCustomer(id);
+        customerService.deleteCustomer(id);
         return true;
     }
 
     /**
      * @see org.apache.click.Page#onRender()
      */
+    @Override
     public void onRender() {
-        List customers = getCustomerService().getCustomersSortedByName(12);
+        List customers = customerService.getCustomersSortedByName(12);
         table.setRowList(customers);
     }
 

Modified: incubator/click/trunk/click/examples/src/org/apache/click/examples/page/table/TableFooter.java
URL: http://svn.apache.org/viewvc/incubator/click/trunk/click/examples/src/org/apache/click/examples/page/table/TableFooter.java?rev=768530&r1=768529&r2=768530&view=diff
==============================================================================
--- incubator/click/trunk/click/examples/src/org/apache/click/examples/page/table/TableFooter.java (original)
+++ incubator/click/trunk/click/examples/src/org/apache/click/examples/page/table/TableFooter.java Sat Apr 25 13:50:28 2009
@@ -21,21 +21,29 @@
 import java.text.MessageFormat;
 import java.util.List;
 
+import javax.annotation.Resource;
+
 import org.apache.click.control.Column;
 import org.apache.click.control.Table;
 import org.apache.click.examples.domain.Customer;
 import org.apache.click.examples.page.BorderPage;
+import org.apache.click.examples.service.CustomerService;
 import org.apache.click.util.HtmlStringBuffer;
+import org.springframework.stereotype.Component;
 
 /**
  * Provides an demonstration of Table control paging.
  *
  * @author Malcolm Edgar
  */
+@Component
 public class TableFooter extends BorderPage {
 
     public Table table;
 
+    @Resource(name="customerService")
+    private CustomerService customerService;
+
     public TableFooter() {
         table = new Table() {
             public void renderFooterRow(HtmlStringBuffer buffer) {
@@ -70,8 +78,9 @@
     /**
      * @see org.apache.click.Page#onRender()
      */
+    @Override
     public void onRender() {
-        List customers = getCustomerService().getCustomersSortedByName(17);
+        List<Customer> customers = customerService.getCustomersSortedByName(17);
         table.setRowList(customers);
     }
 

Modified: incubator/click/trunk/click/examples/src/org/apache/click/examples/page/table/TablePaginatorPage.java
URL: http://svn.apache.org/viewvc/incubator/click/trunk/click/examples/src/org/apache/click/examples/page/table/TablePaginatorPage.java?rev=768530&r1=768529&r2=768530&view=diff
==============================================================================
--- incubator/click/trunk/click/examples/src/org/apache/click/examples/page/table/TablePaginatorPage.java (original)
+++ incubator/click/trunk/click/examples/src/org/apache/click/examples/page/table/TablePaginatorPage.java Sat Apr 25 13:50:28 2009
@@ -20,23 +20,32 @@
 
 import java.util.List;
 
+import javax.annotation.Resource;
+
 import org.apache.click.control.Column;
-import org.apache.click.extras.control.TableInlinePaginator;
 import org.apache.click.control.Table;
 import org.apache.click.control.TablePaginator;
+import org.apache.click.examples.domain.Customer;
 import org.apache.click.examples.page.BorderPage;
+import org.apache.click.examples.service.CustomerService;
+import org.apache.click.extras.control.TableInlinePaginator;
+import org.springframework.stereotype.Component;
 
 /**
  * Provides an demonstration of Table pagination options.
  *
  * @author Malcolm Edgar
  */
+@Component
 public class TablePaginatorPage extends BorderPage {
 
     public Table table1 = new Table();
     public Table table2 = new Table();
     public Table table3 = new Table();
 
+    @Resource(name="customerService")
+    private CustomerService customerService;
+
     public TablePaginatorPage() {
         // Table 1
         addColumns(table1);
@@ -58,7 +67,7 @@
      * @see org.apache.click.Page#onRender()
      */
     public void onRender() {
-        List customers = getCustomerService().getCustomers();
+        List<Customer> customers = customerService.getCustomers();
         table1.setRowList(customers);
         table2.setRowList(customers);
         table3.setRowList(customers);

Modified: incubator/click/trunk/click/examples/src/org/apache/click/examples/page/table/TablePaging.java
URL: http://svn.apache.org/viewvc/incubator/click/trunk/click/examples/src/org/apache/click/examples/page/table/TablePaging.java?rev=768530&r1=768529&r2=768530&view=diff
==============================================================================
--- incubator/click/trunk/click/examples/src/org/apache/click/examples/page/table/TablePaging.java (original)
+++ incubator/click/trunk/click/examples/src/org/apache/click/examples/page/table/TablePaging.java Sat Apr 25 13:50:28 2009
@@ -20,19 +20,28 @@
 
 import java.util.List;
 
+import javax.annotation.Resource;
+
 import org.apache.click.control.Column;
 import org.apache.click.control.Table;
+import org.apache.click.examples.domain.Customer;
 import org.apache.click.examples.page.BorderPage;
+import org.apache.click.examples.service.CustomerService;
+import org.springframework.stereotype.Component;
 
 /**
  * Provides an demonstration of Table control paging.
  *
  * @author Malcolm Edgar
  */
+@Component
 public class TablePaging extends BorderPage {
 
     public Table table = new Table();
 
+    @Resource(name="customerService")
+    private CustomerService customerService;
+
     public TablePaging() {
         // Setup customers table
         table.setClass(Table.CLASS_ISI);
@@ -64,8 +73,9 @@
     /**
      * @see org.apache.click.Page#onRender()
      */
+    @Override
     public void onRender() {
-        List customers = getCustomerService().getCustomers();
+        List<Customer> customers = customerService.getCustomers();
         table.setRowList(customers);
     }
 }

Modified: incubator/click/trunk/click/examples/src/org/apache/click/examples/page/table/TableSorting.java
URL: http://svn.apache.org/viewvc/incubator/click/trunk/click/examples/src/org/apache/click/examples/page/table/TableSorting.java?rev=768530&r1=768529&r2=768530&view=diff
==============================================================================
--- incubator/click/trunk/click/examples/src/org/apache/click/examples/page/table/TableSorting.java (original)
+++ incubator/click/trunk/click/examples/src/org/apache/click/examples/page/table/TableSorting.java Sat Apr 25 13:50:28 2009
@@ -20,19 +20,28 @@
 
 import java.util.List;
 
+import javax.annotation.Resource;
+
 import org.apache.click.control.Column;
 import org.apache.click.control.Table;
+import org.apache.click.examples.domain.Customer;
 import org.apache.click.examples.page.BorderPage;
+import org.apache.click.examples.service.CustomerService;
+import org.springframework.stereotype.Component;
 
 /**
  * Provides an demonstration of Table column sorting using a database.
  *
  * @author Malcolm Edgar
  */
+@Component
 public class TableSorting extends BorderPage {
 
     public Table table = new Table();
 
+    @Resource(name="customerService")
+    private CustomerService customerService;
+
     // ------------------------------------------------------------ Constructor
 
     public TableSorting() {
@@ -73,10 +82,11 @@
      *
      * @see org.apache.click.Page#onRender()
      */
+    @Override
     public void onRender() {
-        List customers =
-            getCustomerService().getCustomersSortedBy(table.getSortedColumn(),
-                                                      table.isSortedAscending());
+        List<Customer> customers =
+            customerService.getCustomersSortedBy(table.getSortedColumn(),
+                                                 table.isSortedAscending());
 
         table.setRowList(customers);
         table.setSorted(true);

Modified: incubator/click/trunk/click/examples/src/org/apache/click/examples/page/table/TableStyles.java
URL: http://svn.apache.org/viewvc/incubator/click/trunk/click/examples/src/org/apache/click/examples/page/table/TableStyles.java?rev=768530&r1=768529&r2=768530&view=diff
==============================================================================
--- incubator/click/trunk/click/examples/src/org/apache/click/examples/page/table/TableStyles.java (original)
+++ incubator/click/trunk/click/examples/src/org/apache/click/examples/page/table/TableStyles.java Sat Apr 25 13:50:28 2009
@@ -20,20 +20,26 @@
 
 import java.util.List;
 
+import javax.annotation.Resource;
+
 import org.apache.click.control.Checkbox;
 import org.apache.click.control.Column;
 import org.apache.click.control.Form;
-import org.apache.click.extras.control.TableInlinePaginator;
 import org.apache.click.control.Label;
 import org.apache.click.control.Select;
 import org.apache.click.control.Table;
+import org.apache.click.examples.domain.Customer;
 import org.apache.click.examples.page.BorderPage;
+import org.apache.click.examples.service.CustomerService;
+import org.apache.click.extras.control.TableInlinePaginator;
+import org.springframework.stereotype.Component;
 
 /**
  * Provides an demonstration of Table control styles.
  *
  * @author Malcolm Edgar
  */
+@Component
 public class TableStyles extends BorderPage {
 
     public Form form = new Form();
@@ -42,6 +48,9 @@
     private Select styleSelect = new Select("style", "Table Style:");
     private Checkbox hoverCheckbox = new Checkbox("hover", "Hover Rows:");
 
+    @Resource(name="customerService")
+    private CustomerService customerService;
+
     // ----------------------------------------------------------- Constructor
 
     public TableStyles() {
@@ -101,11 +110,12 @@
     /**
      * @see org.apache.click.Page#onRender()
      */
+    @Override
     public void onRender() {
         table.setClass(styleSelect.getValue());
         table.setHoverRows(hoverCheckbox.isChecked());
 
-        List customers = getCustomerService().getCustomers();
+        List<Customer> customers = customerService.getCustomers();
         table.setRowList(customers);
     }
 

Modified: incubator/click/trunk/click/examples/src/org/apache/click/examples/page/velocity/ActionTable.java
URL: http://svn.apache.org/viewvc/incubator/click/trunk/click/examples/src/org/apache/click/examples/page/velocity/ActionTable.java?rev=768530&r1=768529&r2=768530&view=diff
==============================================================================
--- incubator/click/trunk/click/examples/src/org/apache/click/examples/page/velocity/ActionTable.java (original)
+++ incubator/click/trunk/click/examples/src/org/apache/click/examples/page/velocity/ActionTable.java Sat Apr 25 13:50:28 2009
@@ -20,12 +20,16 @@
 
 import java.util.List;
 
+import javax.annotation.Resource;
+
 import org.apache.click.Page;
 import org.apache.click.control.ActionLink;
 import org.apache.click.control.PageLink;
 import org.apache.click.examples.domain.Customer;
 import org.apache.click.examples.page.BorderPage;
 import org.apache.click.examples.page.EditCustomer;
+import org.apache.click.examples.service.CustomerService;
+import org.springframework.stereotype.Component;
 
 /**
  * Provides a dynamic ActionLink and PageLink example in a HTML table.
@@ -36,6 +40,7 @@
  *
  * @author Malcolm Edgar
  */
+@Component
 public class ActionTable extends BorderPage {
 
     public List customers;
@@ -44,6 +49,10 @@
     public PageLink editLink = new PageLink(EditCustomer.class);
     public ActionLink deleteLink = new ActionLink(this, "onDeleteClick");
 
+    @Resource(name="customerService")
+    private CustomerService customerService;
+
+    @Override
     public void onInit() {
         super.onInit();
 
@@ -53,14 +62,14 @@
 
     public boolean onViewClick() {
         Integer id = viewLink.getValueInteger();
-        customerDetail = getCustomerService().getCustomerForID(id);
+        customerDetail = customerService.getCustomerForID(id);
 
         return true;
     }
 
     public boolean onDeleteClick() {
         Integer id = deleteLink.getValueInteger();
-        getCustomerService().deleteCustomer(id);
+        customerService.deleteCustomer(id);
 
         return true;
     }
@@ -71,8 +80,9 @@
      *
      * @see Page#onRender()
      */
+    @Override
     public void onRender() {
-        customers = getCustomerService().getCustomersSortedByName(7);
+        customers = customerService.getCustomersSortedByName(7);
         getFormat().setEmptyString("&nbsp;");
     }
 

Modified: incubator/click/trunk/click/examples/src/org/apache/click/examples/page/wizard/SelectPostCode.java
URL: http://svn.apache.org/viewvc/incubator/click/trunk/click/examples/src/org/apache/click/examples/page/wizard/SelectPostCode.java?rev=768530&r1=768529&r2=768530&view=diff
==============================================================================
--- incubator/click/trunk/click/examples/src/org/apache/click/examples/page/wizard/SelectPostCode.java (original)
+++ incubator/click/trunk/click/examples/src/org/apache/click/examples/page/wizard/SelectPostCode.java Sat Apr 25 13:50:28 2009
@@ -19,6 +19,9 @@
 package org.apache.click.examples.page.wizard;
 
 import java.util.List;
+
+import javax.annotation.Resource;
+
 import org.apache.click.Context;
 import org.apache.click.control.AbstractLink;
 import org.apache.click.control.Column;
@@ -26,8 +29,10 @@
 import org.apache.click.control.Table;
 import org.apache.click.examples.domain.PostCode;
 import org.apache.click.examples.page.BorderPage;
+import org.apache.click.examples.service.PostCodeService;
 import org.apache.click.extras.control.LinkDecorator;
 import org.apache.click.util.HtmlStringBuffer;
+import org.springframework.stereotype.Component;
 
 /**
  * This Page provides a table to select the postal code from.
@@ -38,11 +43,15 @@
  *
  * @author Bob Schellink
  */
+@Component
 public class SelectPostCode extends BorderPage {
 
     /** Reference to the table. */
     private Table table = new Table("table");
 
+    @Resource(name="postCodeService")
+    private PostCodeService postCodeService;
+
     /**
      * Default constructor.
      */
@@ -81,7 +90,7 @@
      * Override onRender to populate the table row data.
      */
     public void onRender() {
-        List states = getPostCodeService().getPostCodes();
+        List<PostCode> states = postCodeService.getPostCodes();
         table.setRowList(states);
     }
 }

Modified: incubator/click/trunk/click/examples/src/org/apache/click/examples/service/BookingService.java
URL: http://svn.apache.org/viewvc/incubator/click/trunk/click/examples/src/org/apache/click/examples/service/BookingService.java?rev=768530&r1=768529&r2=768530&view=diff
==============================================================================
--- incubator/click/trunk/click/examples/src/org/apache/click/examples/service/BookingService.java (original)
+++ incubator/click/trunk/click/examples/src/org/apache/click/examples/service/BookingService.java Sat Apr 25 13:50:28 2009
@@ -22,6 +22,7 @@
 
 import org.apache.click.examples.domain.CourseBooking;
 import org.apache.click.extras.cayenne.CayenneTemplate;
+import org.springframework.stereotype.Component;
 
 /**
  * Provides a CourseBooking Service.
@@ -30,6 +31,7 @@
  *
  * @author Malcolm Edgar
  */
+@Component
 public class BookingService extends CayenneTemplate {
 
     public CourseBooking findCourseBookingByID(Integer id) {

Modified: incubator/click/trunk/click/examples/src/org/apache/click/examples/service/ClientService.java
URL: http://svn.apache.org/viewvc/incubator/click/trunk/click/examples/src/org/apache/click/examples/service/ClientService.java?rev=768530&r1=768529&r2=768530&view=diff
==============================================================================
--- incubator/click/trunk/click/examples/src/org/apache/click/examples/service/ClientService.java (original)
+++ incubator/click/trunk/click/examples/src/org/apache/click/examples/service/ClientService.java Sat Apr 25 13:50:28 2009
@@ -24,6 +24,7 @@
 import org.apache.click.extras.cayenne.CayenneTemplate;
 
 import org.apache.cayenne.query.SelectQuery;
+import org.springframework.stereotype.Component;
 
 /**
  * Provides a Client Service.
@@ -32,9 +33,11 @@
  *
  * @author Malcolm Edgar
  */
+@Component
 public class ClientService extends CayenneTemplate {
 
-    public List getClients() {
+    @SuppressWarnings("unchecked")
+    public List<Client> getClients() {
         SelectQuery query = new SelectQuery(Client.class);
         query.addOrdering("db:id", true);
         return performQuery(query);

Modified: incubator/click/trunk/click/examples/src/org/apache/click/examples/service/CustomerService.java
URL: http://svn.apache.org/viewvc/incubator/click/trunk/click/examples/src/org/apache/click/examples/service/CustomerService.java?rev=768530&r1=768529&r2=768530&view=diff
==============================================================================
--- incubator/click/trunk/click/examples/src/org/apache/click/examples/service/CustomerService.java (original)
+++ incubator/click/trunk/click/examples/src/org/apache/click/examples/service/CustomerService.java Sat Apr 25 13:50:28 2009
@@ -37,6 +37,7 @@
 import org.apache.cayenne.query.SQLTemplate;
 import org.apache.cayenne.query.SelectQuery;
 import org.apache.commons.lang.math.NumberUtils;
+import org.springframework.stereotype.Component;
 
 /**
  * Provides a Customer Service.
@@ -45,14 +46,17 @@
  *
  * @author Malcolm Edgar
  */
+@Component
 public class CustomerService extends CayenneTemplate {
 
-    public List getCustomers() {
+    @SuppressWarnings("unchecked")
+    public List<Customer> getCustomers() {
         SelectQuery query = new SelectQuery(Customer.class);
         query.addOrdering(Customer.NAME_PROPERTY, true);
         return performQuery(query);
     }
 
+    @SuppressWarnings("unchecked")
     public int getNumberOfCustomers() {
         CountQuery query = new CountQuery(Customer.class);
         List result = performQuery(query);
@@ -61,7 +65,8 @@
         return count.intValue();
     }
 
-    public List getCustomersSortedBy(String property, boolean ascending) {
+    @SuppressWarnings("unchecked")
+    public List<Customer> getCustomersSortedBy(String property, boolean ascending) {
         SelectQuery query = new SelectQuery(Customer.class);
         if (property != null) {
             query.addOrdering(property, ascending);
@@ -69,7 +74,8 @@
         return performQuery(query);
     }
 
-    public List getCustomers(String name, Date startDate) {
+    @SuppressWarnings("unchecked")
+    public List<Customer> getCustomers(String name, Date startDate) {
         SelectQuery query = new SelectQuery(Customer.class);
 
         if (StringUtils.isNotBlank(name)) {
@@ -85,7 +91,8 @@
         return performQuery(query);
     }
 
-    public List getCustomerNamesLike(String name) {
+    @SuppressWarnings("unchecked")
+    public List<Customer> getCustomerNamesLike(String name) {
         SelectQuery query = new SelectQuery(Customer.class);
 
         query.andQualifier(ExpressionFactory.likeIgnoreCaseExp(Customer.NAME_PROPERTY, "%" + name + "%"));
@@ -103,7 +110,8 @@
         return list;
     }
 
-    public List getCustomers(Date from, Date to) {
+    @SuppressWarnings("unchecked")
+    public List<Customer> getCustomers(Date from, Date to) {
         Expression qual = ExpressionFactory.noMatchExp(Customer.DATE_JOINED_PROPERTY, null);
 
         if (from != null) {
@@ -119,14 +127,16 @@
         return performQuery(query);
     }
 
-    public List getCustomersSortedByName(int rows) {
+    @SuppressWarnings("unchecked")
+    public List<Customer> getCustomersSortedByName(int rows) {
         SelectQuery query = new SelectQuery(Customer.class);
         query.addOrdering(Customer.NAME_PROPERTY, true);
         query.setFetchLimit(rows);
         return performQuery(query);
     }
 
-    public List getCustomersSortedByDateJoined(int rows) {
+    @SuppressWarnings("unchecked")
+    public List<Customer> getCustomersSortedByDateJoined(int rows) {
         SelectQuery query = new SelectQuery(Customer.class);
         query.addOrdering(Customer.DATE_JOINED_PROPERTY, true);
         query.setFetchLimit(rows);
@@ -160,6 +170,7 @@
         }
     }
 
+    @SuppressWarnings("unchecked")
     public Customer findCustomerByName(String name) {
         SelectQuery query = new SelectQuery(Customer.class);
         query.andQualifier(ExpressionFactory.matchExp(Customer.NAME_PROPERTY,name));
@@ -173,18 +184,21 @@
         }
     }
 
-    public List getCustomersForName(String value) {
+    @SuppressWarnings("unchecked")
+    public List<Customer> getCustomersForName(String value) {
         Expression template = Expression.fromString("name likeIgnoreCase $name");
         Expression e = template.expWithParameters(toMap(Customer.NAME_PROPERTY, "%" + value + "%"));
         return  performQuery(new SelectQuery(Customer.class, e));
     }
 
-    public List getCustomersForAge(String value) {
+    @SuppressWarnings("unchecked")
+    public List<Customer> getCustomersForAge(String value) {
         int age = NumberUtils.toInt(value);
         return performQuery(Customer.class, Customer.AGE_PROPERTY, new Integer(age));
     }
 
-    public List getCustomersForPage(int offset, int pageSize) {
+    @SuppressWarnings("unchecked")
+    public List<Customer> getCustomersForPage(int offset, int pageSize) {
         List list = getCustomers();
 
         List pageList = new ArrayList(pageSize);
@@ -202,7 +216,8 @@
         return pageList;
     }
 
-    public List getInvestmentCatetories() {
+    @SuppressWarnings("unchecked")
+    public List<Customer> getInvestmentCatetories() {
         List categories = new ArrayList();
 
         categories.add("Bonds");
@@ -219,6 +234,8 @@
      */
     class CountQuery extends IndirectQuery {
 
+        private static final long serialVersionUID = 1L;
+
         protected Class objectClass;
 
         public CountQuery(Class objectClass) {

Modified: incubator/click/trunk/click/examples/src/org/apache/click/examples/service/PostCodeService.java
URL: http://svn.apache.org/viewvc/incubator/click/trunk/click/examples/src/org/apache/click/examples/service/PostCodeService.java?rev=768530&r1=768529&r2=768530&view=diff
==============================================================================
--- incubator/click/trunk/click/examples/src/org/apache/click/examples/service/PostCodeService.java (original)
+++ incubator/click/trunk/click/examples/src/org/apache/click/examples/service/PostCodeService.java Sat Apr 25 13:50:28 2009
@@ -25,6 +25,7 @@
 
 import org.apache.click.examples.domain.PostCode;
 import org.apache.click.extras.cayenne.CayenneTemplate;
+import org.springframework.stereotype.Component;
 
 /**
  * Provides a Postcode Service.
@@ -33,9 +34,11 @@
  *
  * @author Malcolm Edgar
  */
+@Component
 public class PostCodeService extends CayenneTemplate {
 
-    public List getPostCodeLocations(String location) {
+    @SuppressWarnings("unchecked")
+    public List<PostCode> getPostCodeLocations(String location) {
         SelectQuery query = new SelectQuery(PostCode.class);
 
         query.andQualifier(ExpressionFactory.likeIgnoreCaseExp(PostCode.LOCALITY_PROPERTY, location + "%"));
@@ -55,7 +58,8 @@
         return list;
     }
 
-    public List getPostCodes() {
+    @SuppressWarnings("unchecked")
+    public List<PostCode> getPostCodes() {
         SelectQuery query = new SelectQuery(PostCode.class);
 
         query.setFetchLimit(10);

Modified: incubator/click/trunk/click/examples/src/org/apache/click/examples/service/UserService.java
URL: http://svn.apache.org/viewvc/incubator/click/trunk/click/examples/src/org/apache/click/examples/service/UserService.java?rev=768530&r1=768529&r2=768530&view=diff
==============================================================================
--- incubator/click/trunk/click/examples/src/org/apache/click/examples/service/UserService.java (original)
+++ incubator/click/trunk/click/examples/src/org/apache/click/examples/service/UserService.java Sat Apr 25 13:50:28 2009
@@ -20,6 +20,7 @@
 
 import org.apache.click.examples.domain.User;
 import org.apache.click.extras.cayenne.CayenneTemplate;
+import org.springframework.stereotype.Component;
 
 /**
  * Provides a User Service.
@@ -28,6 +29,7 @@
  *
  * @author Malcolm Edgar
  */
+@Component
 public class UserService extends CayenneTemplate {
 
     public boolean isAuthenticatedUser(User user) {

Modified: incubator/click/trunk/click/examples/webapp/WEB-INF/menu.xml
URL: http://svn.apache.org/viewvc/incubator/click/trunk/click/examples/webapp/WEB-INF/menu.xml?rev=768530&r1=768529&r2=768530&view=diff
==============================================================================
--- incubator/click/trunk/click/examples/webapp/WEB-INF/menu.xml (original)
+++ incubator/click/trunk/click/examples/webapp/WEB-INF/menu.xml Sat Apr 25 13:50:28 2009
@@ -26,6 +26,7 @@
     <menu label="Javadoc API" path="javadoc/index.html" title="Examples HTML Javadoc API" target="_blank" />
     <menu separator="true"/>
     <menu label="click.xml" path="source-viewer.htm?filename=WEB-INF/click.xml" title="Click application descriptor" target="_blank" />
+    <menu label="spring-beans.xml" path="source-viewer.htm?filename=WEB-INF/spring-beans.xml" title="Spring beans descriptor" target="_blank" />
     <menu label="web.xml" path="source-viewer.htm?filename=WEB-INF/web.xml" title="Web application descriptor" target="_blank" />
   </menu>
 

Copied: incubator/click/trunk/click/examples/webapp/WEB-INF/spring-beans.xml (from r764291, incubator/click/trunk/click/examples/src/applicationContext.xml)
URL: http://svn.apache.org/viewvc/incubator/click/trunk/click/examples/webapp/WEB-INF/spring-beans.xml?p2=incubator/click/trunk/click/examples/webapp/WEB-INF/spring-beans.xml&p1=incubator/click/trunk/click/examples/src/applicationContext.xml&r1=764291&r2=768530&rev=768530&view=diff
==============================================================================
--- incubator/click/trunk/click/examples/src/applicationContext.xml (original)
+++ incubator/click/trunk/click/examples/webapp/WEB-INF/spring-beans.xml Sat Apr 25 13:50:28 2009
@@ -17,19 +17,14 @@
    specific language governing permissions and limitations
    under the License.
 -->
-<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" 
-	"http://www.springframework.org/dtd/spring-beans.dtd">
-    
-<beans>
-    
-    <bean id="bookingService" class="org.apache.click.examples.service.BookingService"/>
-    
-    <bean id="clientService" class="org.apache.click.examples.service.ClientService"/>
-    
-    <bean id="customerService" class="org.apache.click.examples.service.CustomerService"/>
-    
-    <bean id="postCodeService" class="org.apache.click.examples.service.PostCodeService"/>
-        
-    <bean id="userService" class="org.apache.click.examples.service.UserService"/>
 
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:context="http://www.springframework.org/schema/context"
+       xsi:schemaLocation="
+       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
+		
+ 	<context:component-scan base-package="org.apache.click.examples" scope-resolver="org.apache.click.extras.spring.PageScopeResolver"/>
+    
 </beans>
\ No newline at end of file

Modified: incubator/click/trunk/click/examples/webapp/WEB-INF/web.xml
URL: http://svn.apache.org/viewvc/incubator/click/trunk/click/examples/webapp/WEB-INF/web.xml?rev=768530&r1=768529&r2=768530&view=diff
==============================================================================
--- incubator/click/trunk/click/examples/webapp/WEB-INF/web.xml (original)
+++ incubator/click/trunk/click/examples/webapp/WEB-INF/web.xml Sat Apr 25 13:50:28 2009
@@ -1,130 +1,139 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<!--
-   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.
--->
-
-<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
-    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
-    version="2.4">
-    
-	<display-name>Click Examples</display-name>
-
-	<!-- 
-	Provides an in memory databae initialization filter. In a production 
-	application a separate database would be used, and this filter would not
-	be needed.
-	-->
-	<filter>
-		<filter-name>DatabaseInitFilter</filter-name>
-		<filter-class>org.apache.click.examples.util.DatabaseInitFilter</filter-class>
-	</filter>
- 
-	<!--
-	Provides a thread local Cayenne DataContext filter.
-	-->
-	<filter>
-		<filter-name>DataContextFilter</filter-name>
-		<filter-class>org.apache.click.extras.cayenne.DataContextFilter</filter-class>
-		<init-param>
-			<param-name>session-scope</param-name>
- 			<param-value>false</param-value>
-		</init-param>
-	</filter>
- 
-	<!-- 
-	Provides a web application performance filter which compresses the response
-	and sets the Expires header on selected static resources. 
-	The "cachable-paths" init parameter tells the filter resources can have 
-	their Expires header set so the browser will cache them.
-  The "excludes-path" init parameter tells the filter which requests should
-	be ignored by the filter.
-	-->
-	<filter>
-		<filter-name>PerformanceFilter</filter-name>
-		<filter-class>org.apache.click.extras.filter.PerformanceFilter</filter-class>
-		<init-param>
-			<param-name>cachable-paths</param-name>
- 			<param-value>/assets/*</param-value>
-		</init-param>
-    <init-param>
-			<param-name>exclude-paths</param-name>
- 			<param-value>*/excel-export.htm</param-value>
-		</init-param>
-	</filter>
-
- 	<filter-mapping>
-		<filter-name>DatabaseInitFilter</filter-name>
-		<servlet-name>ClickServlet</servlet-name>
-	</filter-mapping>
-
-	<filter-mapping>
-		<filter-name>DataContextFilter</filter-name>
-		<servlet-name>ClickServlet</servlet-name>
-	</filter-mapping>
-
-	<filter-mapping>
-		<filter-name>PerformanceFilter</filter-name>
-		<servlet-name>ClickServlet</servlet-name>
-	</filter-mapping>
-
-	<filter-mapping>
-		<filter-name>PerformanceFilter</filter-name>
-		<url-pattern>*.css</url-pattern>
-	</filter-mapping>
-	
-	<filter-mapping>
-		<filter-name>PerformanceFilter</filter-name>
-		<url-pattern>*.js</url-pattern>
-	</filter-mapping>
-	
-	<filter-mapping>
-		<filter-name>PerformanceFilter</filter-name>
-		<url-pattern>*.gif</url-pattern>
-	</filter-mapping>
-	
-	<filter-mapping>
-		<filter-name>PerformanceFilter</filter-name>
-		<url-pattern>*.png</url-pattern>
-	</filter-mapping>
-
-	<!--
-	The Spring Click Servlet which handles *.htm requests. The "spring-path"
-	init parameter tells the servlet where to find the Spring application
-	context file on the classpath.
-	-->
-	<servlet>
-		<servlet-name>ClickServlet</servlet-name>
-		<servlet-class>org.apache.click.extras.spring.SpringClickServlet</servlet-class>
-		<init-param>
-			<param-name>spring-path</param-name>
-			<param-value>/applicationContext.xml</param-value>
-		</init-param>
-		<load-on-startup>0</load-on-startup>
-	</servlet>
-
-	<servlet-mapping>
-		<servlet-name>ClickServlet</servlet-name>
-		<url-pattern>*.htm</url-pattern>
-	</servlet-mapping>
-
-	<welcome-file-list>
-		<welcome-file>redirect.html</welcome-file>
-	</welcome-file-list>
-
-</web-app>
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+   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.
+-->
+
+<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
+    version="2.4">
+    
+	<display-name>Click Examples</display-name>
+	
+	<!-- 
+	Spring configuration location. 
+	-->
+	<context-param>
+		<param-name>contextConfigLocation</param-name>
+		<param-value>WEB-INF/spring-beans.xml</param-value>
+	</context-param>
+
+	<!-- 
+	Provides an in memory databae initialization filter. In a production 
+	application a separate database would be used, and this filter would not
+	be needed.
+	-->
+	<filter>
+		<filter-name>DatabaseInitFilter</filter-name>
+		<filter-class>org.apache.click.examples.util.DatabaseInitFilter</filter-class>
+	</filter>
+ 
+	<!--
+	Provides a thread local Cayenne DataContext filter.
+	-->
+	<filter>
+		<filter-name>DataContextFilter</filter-name>
+		<filter-class>org.apache.click.extras.cayenne.DataContextFilter</filter-class>
+		<init-param>
+			<param-name>session-scope</param-name>
+ 			<param-value>false</param-value>
+		</init-param>
+	</filter>
+ 
+	<!-- 
+	Provides a web application performance filter which compresses the response
+	and sets the Expires header on selected static resources. 
+	The "cachable-paths" init parameter tells the filter resources can have 
+	their Expires header set so the browser will cache them.
+	The "excludes-path" init parameter tells the filter which requests should
+	be ignored by the filter.
+	-->
+	<filter>
+		<filter-name>PerformanceFilter</filter-name>
+		<filter-class>org.apache.click.extras.filter.PerformanceFilter</filter-class>
+		<init-param>
+			<param-name>cachable-paths</param-name>
+ 			<param-value>/assets/*</param-value>
+		</init-param>
+		<init-param>
+			<param-name>exclude-paths</param-name>
+ 			<param-value>*/excel-export.htm</param-value>
+		</init-param>
+	</filter>
+
+ 	<filter-mapping>
+		<filter-name>DatabaseInitFilter</filter-name>
+		<servlet-name>ClickServlet</servlet-name>
+	</filter-mapping>
+
+	<filter-mapping>
+		<filter-name>DataContextFilter</filter-name>
+		<servlet-name>ClickServlet</servlet-name>
+	</filter-mapping>
+
+	<filter-mapping>
+		<filter-name>PerformanceFilter</filter-name>
+		<servlet-name>ClickServlet</servlet-name>
+	</filter-mapping>
+
+	<filter-mapping>
+		<filter-name>PerformanceFilter</filter-name>
+		<url-pattern>*.css</url-pattern>
+	</filter-mapping>
+	
+	<filter-mapping>
+		<filter-name>PerformanceFilter</filter-name>
+		<url-pattern>*.js</url-pattern>
+	</filter-mapping>
+	
+	<filter-mapping>
+		<filter-name>PerformanceFilter</filter-name>
+		<url-pattern>*.gif</url-pattern>
+	</filter-mapping>
+	
+	<filter-mapping>
+		<filter-name>PerformanceFilter</filter-name>
+		<url-pattern>*.png</url-pattern>
+	</filter-mapping>
+	
+	<!-- 
+	The Spring Context Loader which initializes the Spring runtime. 
+	-->
+	<listener>
+		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
+	</listener>
+
+	<!--
+	The Spring Click Servlet which handles *.htm requests.
+	-->
+	<servlet>
+		<servlet-name>SpringClickServlet</servlet-name>
+		<servlet-class>org.apache.click.extras.spring.SpringClickServlet</servlet-class>
+		<load-on-startup>0</load-on-startup>
+	</servlet>
+
+	<servlet-mapping>
+		<servlet-name>SpringClickServlet</servlet-name>
+		<url-pattern>*.htm</url-pattern>
+	</servlet-mapping>
+
+	<welcome-file-list>
+		<welcome-file>redirect.html</welcome-file>
+	</welcome-file-list>
+
+</web-app>

Added: incubator/click/trunk/click/extras/src/org/apache/click/extras/spring/PageScopeResolver.java
URL: http://svn.apache.org/viewvc/incubator/click/trunk/click/extras/src/org/apache/click/extras/spring/PageScopeResolver.java?rev=768530&view=auto
==============================================================================
--- incubator/click/trunk/click/extras/src/org/apache/click/extras/spring/PageScopeResolver.java (added)
+++ incubator/click/trunk/click/extras/src/org/apache/click/extras/spring/PageScopeResolver.java Sat Apr 25 13:50:28 2009
@@ -0,0 +1,116 @@
+/*
+ * 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.
+ */
+package org.apache.click.extras.spring;
+
+import org.apache.click.Page;
+import org.apache.click.util.ClickUtils;
+
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.config.ConfigurableBeanFactory;
+import org.springframework.context.annotation.ScopeMetadata;
+import org.springframework.context.annotation.ScopeMetadataResolver;
+
+/**
+ * Provides a Spring bean scope resolver when using Spring
+ * instantiated pages with the &#64;Component annotation.
+ * <p/>
+ * This scope meta data resolver will resolve "prototype" scope for any Click Page bean,
+ * otherwise it will resolve "singleton" scope.
+ *
+ * <h3>Example &#64;Component Page</h3>
+ * An example Page class is provided below which uses the Spring &#64;Component annotation.
+ *
+ * <pre class="codeJava">
+ * <span class="kw">package</span> com.mycorp.page;
+ *
+ * <span class="kw">import</span> javax.annotation.Resource;
+ * <span class="kw">import</span> org.apache.click.Page;
+ * <span class="kw">import</span> org.springframework.stereotype.Component;
+ *
+ * <span class="kw">import</span> comp.mycorp.service.CustomerService;
+ *
+ * <span class="green">&#64;Component</span>
+ * <span class="kw">public class</span> CustomerEditPage <span class="kw">extends</span> Page {
+ *
+ *     <span class="green">&#64;Resource</span>(name=<span class="st">"customerService"</span>)
+ *     <span class="kw">private</span> CustomerService customerService;
+ *
+ *     ..
+ * } </pre>
+ *
+ * Note in this example page the customerService with the &#64;Resource
+ * annotation is injected by Spring after the page instance has been instantiated.
+ *
+ * <h3>Example Spring Configuration</h3>
+ * An example Spring XML configuration is provided below.
+ *
+ * <pre class="codeConfig">
+ * &lt;?xml version="1.0" encoding="UTF-8"?&gt;
+ * &lt;beans xmlns="http://www.springframework.org/schema/beans"
+ *      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ *      xmlns:context="http://www.springframework.org/schema/context"
+ *      xsi:schemaLocation="
+ *      http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+ *      http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"&gt;
+ *
+ *   &lt;context:component-scan base-package="<span class="red">com.mycorp</span>" scope-resolver=<span class="blue">"org.apache.click.extras.spring.PageScopeResolver"</span>/&gt;
+ *
+ * &lt;/beans&gt; </pre>
+ *
+ * In this example any page class under the base package "com.mycorp" which is
+ * includes &#64;Component annotation will have "prototype" scope.
+ *
+ * @see SpringClickServlet
+ *
+ * @author Malcolm Edgar
+ */
+public class PageScopeResolver implements ScopeMetadataResolver {
+
+    /**
+     * Return the scope meta data for the given bean definition. This scope meta
+     * data resolver will resolve "prototype" scope for any Click Page bean or will
+     * resolve "singleton" scope otherwise.
+     *
+     * @see ScopeMetadataResolver#resolveScopeMetadata(BeanDefinition)
+     *
+     * @param beanDef the component bean definition to resolve
+     * @return the scope meta data for the given bean definition.
+     */
+    public ScopeMetadata resolveScopeMetadata(BeanDefinition beanDef) {
+        ScopeMetadata sm = new ScopeMetadata();
+
+        try {
+            Class beanClass = ClickUtils.classForName(beanDef.getBeanClassName());
+
+            if (Page.class.isAssignableFrom(beanClass)) {
+                sm.setScopeName(ConfigurableBeanFactory.SCOPE_PROTOTYPE);
+
+            } else {
+                sm.setScopeName(ConfigurableBeanFactory.SCOPE_SINGLETON);
+            }
+
+            return sm;
+
+        } catch (Exception e) {
+            String msg = "Could not load class for beanDef: " + beanDef;
+            throw new RuntimeException(msg, e);
+        }
+    }
+
+}

Modified: incubator/click/trunk/click/extras/src/org/apache/click/extras/spring/SpringClickServlet.java
URL: http://svn.apache.org/viewvc/incubator/click/trunk/click/extras/src/org/apache/click/extras/spring/SpringClickServlet.java?rev=768530&r1=768529&r2=768530&view=diff
==============================================================================
--- incubator/click/trunk/click/extras/src/org/apache/click/extras/spring/SpringClickServlet.java (original)
+++ incubator/click/trunk/click/extras/src/org/apache/click/extras/spring/SpringClickServlet.java Sat Apr 25 13:50:28 2009
@@ -18,6 +18,14 @@
  */
 package org.apache.click.extras.spring;
 
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
 import javax.servlet.ServletContext;
 import javax.servlet.ServletException;
 import javax.servlet.UnavailableException;
@@ -25,6 +33,7 @@
 
 import org.apache.click.ClickServlet;
 import org.apache.click.Page;
+import org.apache.click.util.HtmlStringBuffer;
 
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.ApplicationContextAware;
@@ -32,224 +41,270 @@
 import org.springframework.web.context.support.WebApplicationContextUtils;
 
 /**
- * Provides an example Spring framework integration <tt>SpringClickServlet</tt>.
+ * Provides an Spring framework integration <tt>SpringClickServlet</tt>.
+ * <p/>
+ * This Spring integration servlet provides a number of integration options
+ * using Spring with Click pages. These options detailed below.
  *
- * <h3>Page Creation</h3>
+ * <h3>Spring instantiated Pages with &#64;Component configuration</h3>
  *
- * This specialized Click Servlet can inject Spring dependencies into
- * defined spring Page beans. If a requested Page is not configured as a Spring
- * bean, then a plain new Page instance is created.
+ * With this option Page classes are configured with Spring using the
+ * &#64;Component annotation. When the SpringClickServlet receives a page
+ * request converts the auto-mapped page class to the equivalent Spring
+ * bean name and gets a new instance from the Spring ApplicationContext.
+ *
+ * <pre class="codeConfig">
+ * customer-list.htm  ->  com.mycorp.page.CustomerListPage  -> customerListPage
+ * HTML Request           Click Page Class                     Spring Bean Name </pre>
+ *
+ * When using this strategy use the PageScopeResolver class to ensure new Page
+ * instances are created with each request, rather than Spring's default
+ * "singleton" creation policy. Please see the {@link PageScopeResolver} Javadoc
+ * for more information on configuring this option.
  * <p/>
- * The SpringClickServlet overrides the ClickServlet method <tt>newPageInstance()</tt>
- * to provide new Page instances:
+ * An example Page class is provided below which uses the Spring &#64;Component annotation.
+ * Note in this example page the customerService with the &#64;Resource
+ * annotation is injected by Spring after the page instance has been instantiated.
  *
  * <pre class="codeJava">
- * <span class="kw">protected</span> Page newPageInstance(String path, Class pageClass, HttpServletRequest request)
- *     <span class="kw">throws</span> Exception {
+ * <span class="kw">package</span> com.mycorp.page;
  *
- *     Page page = <span class="kw">null</span>;
+ * <span class="kw">import</span> javax.annotation.Resource;
+ * <span class="kw">import</span> org.apache.click.Page;
+ * <span class="kw">import</span> org.springframework.stereotype.Component;
  *
- *     String beanName = pageClass.getName();
+ * <span class="kw">import</span> com.mycorp.service.CustomerService;
  *
- *     <span class="kw">if</span> (applicationContext.containsBean(beanName)) {
- *         Page page = (Page) applicationContext.getBean(beanName);
+ * <span class="green">&#64;Component</span>
+ * <span class="kw">public class</span> CustomerListPage <span class="kw">extends</span> Page {
  *
- *     } <span class="kw">else</span> {
- *         page = (Page) pageClass.newIntance();
- *     }
+ *     <span class="green">&#64;Resource</span>(name=<span class="st">"customerService"</span>)
+ *     <span class="kw">private</span> CustomerService customerService;
  *
- *     <span class="kw">return</span> page;
+ *     ..
  * } </pre>
  *
- * The SpringClickServlet support Spring Page injection in two ways.
+ * This is the most powerful and convenient Spring integration option, but does
+ * require Spring 2.5.x and Java 1.5 or latter.
+ *
+ * <h3>Spring instantiated Pages with Spring XML configuration</h3>
+ *
+ * With this option Page classes are configured using Spring XML configuration.
+ * When the SpringClickServlet receives a page request converts the auto-mapped
+ * page class to the equivalent Spring bean name and gets a new instance from the
+ * Spring ApplicationContext.
+ *
+ * <pre class="codeConfig">
+ * customer-list.htm  ->  com.mycorp.page.CustomerListPage  -> customerListPage
+ * HTML Request           Click Page Class                     Spring Bean Name </pre>
+ *
+ * If the page bean is not found in the ApplicationContxt then the full Page
+ * class name is used.
+ *
+ * <pre class="codeConfig">
+ * customer-list.htm  ->  com.mycorp.page.CustomerListPage  -> com.mycorp.page.CustomerListPage
+ * HTML Request           Click Page Class                     Spring Bean Name </pre>
  *
- * <h4>Click Instantiated Pages</h4>
+ * This integration option requires you to configure all your Spring Page beans
+ * in your Spring XML configuration. While this may be quite laborious, it does
+ * support Spring 1.x and Java 1.4. An example page bean configuration is
+ * provided below:
  *
- * With Click instantiated pages you have your Page classes implement the Spring
- * {@link org.springframework.context.ApplicationContextAware} interface.
- * The SpringClickServlet then create the Page instance an inject the Spring
- * <tt>ApplicationContext</tt> instance.
+ * <pre class="codeConfig">
+ * &lt;?xml version="1.0" encoding="UTF-8"?&gt;
+ * &lt;beans&gt;
+ *
+ *    &lt;bean id="customerListPage" class="com.mycorp.page.CustomerListPage" scope="prototype"/&gt;
+ *
+ * &lt;/beans&gt; </pre>
+ *
+ * <b>Please Note</b> ensure the page beans scope is set to "prototype" so a new \
+ * page instance will be created with every HTTP request. Otherwise Spring will
+ * default to using singletons and your code will not be thread safe.
+ *
+ * <h3>Click instantiated Pages with injected Spring beans and/or ApplicationContext</h3>
+ *
+ * With this integration option Click will instantiate page instances and
+ * automatically inject any page properties which match Spring beans defined in
+ * the ApplicationContext.
  * <p/>
- * The advantage of using this technique is that you don't need to
- * define your Pages as beans in Spring configuration files. However you will
- * need hard code acessor methods in you Click pages. For example:
+ * While this option is not as powerful as &#64;Component configured pages it is
+ * much more convenient than Spring XML configured pages and supports Spring 1.x and Java 1.4.
+ * <p/>
+ * An example Page class is provided below which has the customerService property
+ * automatically injected by the SpringClickServlet. Note the customerService
+ * property will need to be defined in a Spring XML configuration.
  *
  * <pre class="codeJava">
- * <span class="kw">public class</span> SpringPage <span class="kw">extends</span> Page <span class="kw">implements</span> ApplicationContextAware {
+ * <span class="kw">package</span> com.mycorp.page;
  *
- *     <span class="kw">protected</span> ApplicationContext applicationContext;
+ * <span class="kw">import</span> org.apache.click.Page;
  *
- *     <span class="kw">public void</span> setApplicationContext(ApplicationContext applicationContext)  {
- *         <span class="kw">this</span>.applicationContext = applicationContext;
- *     }
+ * <span class="kw">import</span> com.mycorp.service.CustomerService;
  *
- *     <span class="kw">public</span> Object getBean(String beanName) {
- *         <span class="kw">return</span> applicationContext.getBean(beanName);
- *     }
+ * <span class="kw">public class</span> CustomerListPage <span class="kw">extends</span> Page {
  *
- *     <span class="kw">public</span> UserService getUserService() {
- *         <span class="kw">return</span> (UserService) getBean(<span class="st">"userService"</span>);
+ *     <span class="kw">private</span> CustomerService customerService;
+ *
+ *     <span class="kw">public void </span> setCustomerService(CustomerService customerService) {
+ *         <span class="kw">this</span>.customerService = customerService;
  *     }
- * } </pre>
  *
- * <h4>Spring Instantiated Pages</h4>
+ *     ..
+ * } </pre>
  *
- * With Spring instantiated pages you define your Pages as beans in a Spring
- * appliction context XML file. For example in this file the Page bean id maps
- * to the page class name:
+ * Page property bean name must match the bean name defined in the Spring XML
+ * configuration. Continuing our example the Spring XML configuration is provided
+ * below:
  *
  * <pre class="codeConfig">
+ * &lt;?xml version="1.0" encoding="UTF-8"?&gt;
  * &lt;beans&gt;
  *
- *    &lt;bean id="com.mycorp.pages.CustomerEdit" class="com.mycorp.pages.CustomerEdit"
- *         singleton="false"&gt;
- *       &lt;property name="userService" ref="userService"/&gt;
- *    &lt;/bean&gt;
+ *    &lt;bean id="customerService" class="com.mycorp.service.CustomerService"/&gt;
  *
  * &lt;/beans&gt; </pre>
  *
- * <b>Please Note</b> ensure that your Page bean is not a singleton, otherwise
- * the page instance will not be thread safe.
- *<p/>
- * Using this technique the SpringClickServlet will look up the Page bean and
- * have Spring create the page instance and inject all its dependencies.
- *
- * <h4>Developing Page Classes</h4>
- *
- * When developing Click page classes please ensure you place any code which
- * relies upon Spring or Click injected dependencies in the pages
- * <tt>onInit()</tt> method and not in the pages constructor. Any dependencies
- * will not be available in when the pages no-args constructor is invoked.
- *
- * <h3>Application Context Configuration</h3>
- *
- * By convention Spring beans are defined in an <tt>applicationContext.xml</tt>
- * file. The Spring runtime needs to be initialized with location of this
- * file so that it can build up the configured Spring beans. There are two
- * typical location options for the <tt>applicationContext.xml</tt> file.
+ * This option will also automatically inject the ApplicationContext into new
+ * page instances which implement the {@link org.springframework.context.ApplicationContextAware}
+ * interface. Using the applicationContext you can lookup Spring beans manually
+ * in your pages. For example:
  *
- * <h4>WEB-INF Directory</h4>
+ * <pre class="codeJava">
+ * <span class="kw">public class</span> CustomerListPage <span class="kw">extends</span> Page <span class="kw">implements</span> ApplicationContextAware {
  *
- * You can place the file under your WEB-INF directory, adjacent to your web.xml
- * file.
+ *     <span class="kw">protected</span> ApplicationContext applicationContext;
  *
- * <pre class="codeConfig">
- * /WEB-INF/applicationContext.xml </pre>
+ *     <span class="kw">public void</span> setApplicationContext(ApplicationContext applicationContext)  {
+ *         <span class="kw">this</span>.applicationContext = applicationContext;
+ *     }
+ *
+ *     <span class="kw">public</span> CustomerService getCustomerService() {
+ *         <span class="kw">return</span> (CustomerService) applicationContext.getBean(<span class="st">"customerService"</span>);
+ *     }
+ * } </pre>
  *
- * To use this option configure a Spring
- * {@link org.springframework.web.context.ContextLoaderListener} in your
- * <tt>web.xml</tt> file. For example:
+ * This last strategy is probably the least convenient integration option.
+ *
+ * <h3>Servlet Configuration</h3>
+ *
+ * The SpringClickServlet can obtain the ApplicationContext either from
+ * {@link WebApplicationContextUtils} which is configured with a
+ * {@link ContextLoaderListener}. For example:
  *
  * <pre class="codeConfig">
+ * &lt;?xml version="1.0" encoding="UTF-8"?&gt;
  * &lt;web-app&gt;
  *
  *    &lt;listener&gt;
  *       &lt;listener-class&gt;
- *          <font color="blue">org.springframework.web.context.ContextLoaderListener</font>
+ *          <span class="blue">org.springframework.web.context.ContextLoaderListener</span>
  *       &lt;/listener-class&gt;
  *    &lt;/listener&gt;
  *
  *    &lt;servlet&gt;
- *       &lt;servlet-name&gt;click-servlet&lt;/servlet-name&gt;
+ *       &lt;servlet-name&gt;SpringClickServlet&lt;/servlet-name&gt;
  *       &lt;servlet-class&gt;org.apache.click.extras.spring.SpringClickServlet&lt;/servlet-class&gt;
  *       &lt;load-on-startup&gt;0&lt;/load-on-startup&gt;
  *    &lt;/servlet&gt;
  *
- *    &lt;servlet-mapping&gt;
- *       &lt;servlet-name&gt;click-servlet&lt;/servlet-name&gt;
- *       &lt;url-pattern&gt;*.htm&lt;/url-pattern&gt;
- *    &lt;/servlet-mapping&gt;
+ *    ..
  *
  * &lt;/web-app&gt; </pre>
  *
- * The advantage of this configuration option is that any changes made to the
- * <tt>applicationContext.xml</tt> file during development will be
- * automatically loaded by the Spring runtime.
- *
- * <h4>Class Path</h4>
- *
- * The second configuration option is to locate the <tt>applicationContext.xml</tt>
- * file on the class path.
- *
- * <pre class="codeConfig">
- * /WEB-INF/classes/applicationContext.xml </pre>
- *
- * To use this configration option add a
- * <tt class="blue">spring-path</tt> servlet initialization parameter which
- * specifies the files class path location to the <tt>SpringClickServlet</tt>
- * servlet config. For example:
+ * Alternatively you can specify the path to the ApplicationContext as a
+ * servlet init parameter. For example:
  *
  * <pre class="codeConfig">
+ * &lt;?xml version="1.0" encoding="UTF-8"?&gt;
  * &lt;web-app&gt;
  *
  *    &lt;servlet&gt;
- *       &lt;servlet-name&gt;click-servlet&lt;/servlet-name&gt;
+ *       &lt;servlet-name&gt;SpringClickServlet&lt;/servlet-name&gt;
  *       &lt;servlet-class&gt;org.apache.click.extras.spring.SpringClickServlet&lt;/servlet-class&gt;
  *       &lt;init-param&gt;
- *         &lt;param-name&gt;<font color="blue">spring-path</font>&lt;/param-name&gt;
- *         &lt;param-value&gt;<font color="red">/applicationContext.xml</font>&lt;/param-value&gt;
+ *         &lt;param-name&gt;<span class="blue">spring-path</span>&lt;/param-name&gt;
+ *         &lt;param-value&gt;<span class="red">/applicationContext.xml</span>&lt;/param-value&gt;
  *       &lt;/init-param&gt;
  *       &lt;load-on-startup&gt;0&lt;/load-on-startup&gt;
  *    &lt;/servlet&gt;
  *
- *    &lt;servlet-mapping&gt;
- *       &lt;servlet-name&gt;click-servlet&lt;/servlet-name&gt;
- *       &lt;url-pattern&gt;*.htm&lt;/url-pattern&gt;
- *    &lt;/servlet-mapping&gt;
+ *    ..
  *
  * &lt;/web-app&gt; </pre>
  *
- * The advantage of this confirguration option is that you can locate your
- * <tt>applicationContext.xml</tt> file in any classpath location. For instance
- * you may package your Spring business tier objects in a separate JAR file
- * which you include with your web application.
- *
- * <h3>Servlet Intialization</h3>
- *
- * Now that we have discussed the configuration options, below you see how the
- * <tt>ClickSpringServlet</tt> loads the
- * {@link org.springframework.context.ApplicationContext} at
- * startup:
+ * To configure page Spring bean injection you need to configure the
+ * <span class="blue">inject-page-beans</span> servlet init parameter. For
+ * example:
  *
- * <pre class="codeJava">
- * <span class="kw">public void</span> init() <span class="kw">throws</span>ServletException {
- *     <span class="kw">super</span>.init();
+ * <pre class="codeConfig">
+ * &lt;?xml version="1.0" encoding="UTF-8"?&gt;
+ * &lt;web-app&gt;
  *
- *     ServletContext servletContext = getServletContext();
- *     applicationContext =
- *         WebApplicationContextUtils.getWebApplicationContext(servletContext);
- *
- *     <span class="kw">if</span> (applicationContext == <span class="kw">null</span>) {
- *         String springPath = getInitParameter(SPRING_PATH);
- *         <span class="kw">if</span> (springPath == <span class="kw">null</span>) {
- *             String msg = SPRING_PATH + <span class="st">" servlet init parameter not defined"</span>;
- *             <span class="kw">throw new</span> UnavailableException(msg);
- *         }
- *         applicationContext = <span class="kw">new</span> ClassPathXmlApplicationContext(springPath);
- *     }
- * } </pre>
+ *    ..
  *
- * <h3>Examples</h3>
+ *    &lt;servlet&gt;
+ *       &lt;servlet-name&gt;SpringClickServlet&lt;/servlet-name&gt;
+ *       &lt;servlet-class&gt;org.apache.click.extras.spring.SpringClickServlet&lt;/servlet-class&gt;
+ *       &lt;init-param&gt;
+ *         &lt;param-name&gt;<span class="blue">inject-page-beans</span>&lt;/param-name&gt;
+ *         &lt;param-value&gt;<span class="red">true</span>&lt;/param-value&gt;
+ *       &lt;/init-param&gt;
+ *       &lt;load-on-startup&gt;0&lt;/load-on-startup&gt;
+ *    &lt;/servlet&gt;
  *
- * Please see the Click Examples application for a demonstration of Spring integration.
+ *    ..
+ *
+ * &lt;/web-app&gt; </pre>
+ *
+ * @see PageScopeResolver
  *
- * @author Phil Barnes
- * @author Paul Rule
  * @author Malcolm Edgar
+ * @author Paul Rule
+ * @author Phil Barnes
  */
 public class SpringClickServlet extends ClickServlet {
 
     private static final long serialVersionUID = 1L;
 
     /**
-     * The path to the Spring XML appliation context definition file:
-     * &nbsp; <tt>"spring-path"</tt>.
+     * The Servlet initialization parameter name for the option to have the
+     * SpringClickServlet inject Spring beans into page instances: &nbsp;
+     * <tt>"inject-page-beans"</tt>.
+     */
+    public static final String INJECT_PAGE_BEANS = "inject-page-beans";
+
+    /**
+     * The Servlet initialization parameter name for the path to the Spring XML
+     * appliation context definition file: &nbsp; <tt>"spring-path"</tt>.
      */
     public static final String SPRING_PATH = "spring-path";
 
+    /** The set of setter methods to ignore. */
+    static final Set SETTER_METHODS_IGNORE_SET = new HashSet();
+
+    // Initialize the setter method ignore set
+    static {
+        SETTER_METHODS_IGNORE_SET.add("setApplicationContext");
+        SETTER_METHODS_IGNORE_SET.add("setFormat");
+        SETTER_METHODS_IGNORE_SET.add("setForward");
+        SETTER_METHODS_IGNORE_SET.add("setHeader");
+        SETTER_METHODS_IGNORE_SET.add("setHeaders");
+        SETTER_METHODS_IGNORE_SET.add("setPageImports");
+        SETTER_METHODS_IGNORE_SET.add("setPath");
+        SETTER_METHODS_IGNORE_SET.add("setStateful");
+        SETTER_METHODS_IGNORE_SET.add("setRedirect");
+        SETTER_METHODS_IGNORE_SET.add("setTemplate");
+    }
+
     /** Spring application context bean factory. */
     protected ApplicationContext applicationContext;
 
+    /** The list of page injectable Spring beans, keyed on page class name. */
+    protected Map pageSetterBeansMap = new HashMap();
+
+    // Public Methods ----------------------------------------------------------
+
     /**
      * Initialize the SpringClickServlet and the Spring application context
      * bean factory. An Spring <tt>ClassPathXmlApplicationContext</tt> bean
@@ -277,15 +332,55 @@
 
             applicationContext = new ClassPathXmlApplicationContext(springPath);
         }
+
+        String injectPageBeans = getInitParameter(INJECT_PAGE_BEANS);
+        if ("true".equalsIgnoreCase(injectPageBeans)) {
+
+            // Process page classes looking for setter methods which match beans
+            // available in the applicationContext
+            List pageClassList = getConfigService().getPageClassList();
+            for (int i = 0; i < pageClassList.size(); i++) {
+                Class pageClass = (Class) pageClassList.get(i);
+
+                Method[] methods = pageClass.getMethods();
+                for (int j = 0; j < methods.length; j++) {
+                    Method method = methods[j];
+                    String methodName = method.getName();
+
+                    if (methodName.startsWith("set")
+                        && !SETTER_METHODS_IGNORE_SET.contains(methodName)
+                        && method.getParameterTypes().length == 1) {
+
+                        // Get the bean name from the setter method name
+                        HtmlStringBuffer buffer = new HtmlStringBuffer();
+                        buffer.append(Character.toLowerCase(methodName.charAt(3)));
+                        buffer.append(methodName.substring(4));
+                        String beanName = buffer.toString();
+
+                        // If Spring contains the bean then cache in map list
+                        if (getApplicationContext().containsBean(beanName)) {
+                            List beanList = (List) pageSetterBeansMap.get(pageClass);
+                            if (beanList == null) {
+                                beanList = new ArrayList();
+                                pageSetterBeansMap.put(pageClass, beanList);
+                            }
+
+                            beanList.add(new BeanNameAndMethod(beanName, method));
+                        }
+                    }
+                }
+            }
+        }
     }
 
+    // Protected Methods ------------------------------------------------------
+
     /**
      * Create a new Spring Page bean if defined in the application context, or
-     * a new Page instance otherwise. The bean name used is the full class name
-     * of the given pageClass.
+     * a new Page instance otherwise.
      * <p/>
-     * If the Page implements the <tt>ApplicationContextAware</tt> interface
-     * this method will set the application context in the newly created page.
+     * If the "inject-paget-beans" option is enable this method will inject
+     * any Spring beans matching the Page's properties.
      *
      * @see ClickServlet#newPageInstance(String, Class, HttpServletRequest)
      *
@@ -300,19 +395,50 @@
 
         Page page = null;
 
-        String beanName = pageClass.getName();
+        String beanName = toBeanName(pageClass);
+
+        if (getApplicationContext().containsBean(beanName)) {
+            page = (Page) getApplicationContext().getBean(beanName);
 
-        if (applicationContext.containsBean(beanName)) {
-            page = (Page) applicationContext.getBean(beanName);
+        } else if (getApplicationContext().containsBean(pageClass.getName())) {
+            page = (Page) getApplicationContext().getBean(pageClass.getName());
 
         } else {
             page = (Page) pageClass.newInstance();
+
+            // Inject any Spring beans into the page instance
+            if (!pageSetterBeansMap.isEmpty()) {
+                List beanList = (List) pageSetterBeansMap.get(page.getClass());
+                if (beanList != null) {
+                    for (int i = 0; i < beanList.size(); i++) {
+                        BeanNameAndMethod bnam = (BeanNameAndMethod) beanList.get(i);
+                        Object bean = getApplicationContext().getBean(bnam.beanName);
+
+                        try {
+                            Object[] args = { bean };
+                            bnam.method.invoke(page, args);
+
+                        } catch (Exception error) {
+                            throw new RuntimeException(error);
+                        }
+                    }
+                }
+            }
         }
 
         return page;
     }
 
     /**
+     * Return the configured Spring application context.
+     *
+     * @return the configured Spring application context.
+     */
+    protected ApplicationContext getApplicationContext() {
+        return applicationContext;
+    }
+
+    /**
      * This method associates the <tt>ApplicationContext</tt> with any
      * <tt>ApplicationContextAware</tt> pages and supports the deserialized of
      * stateful pages.
@@ -325,7 +451,46 @@
         if (page instanceof ApplicationContextAware) {
             ApplicationContextAware aware =
                 (ApplicationContextAware) page;
-            aware.setApplicationContext(applicationContext);
+            aware.setApplicationContext(getApplicationContext());
+        }
+    }
+
+    /**
+     * Return the Spring beanName for the given class.
+     *
+     * @param aClass the class to get the Spring bean name from
+     * @return the class bean name
+     */
+    protected String toBeanName(Class aClass) {
+        String className = aClass.getName();
+        String beanName = className.substring(className.lastIndexOf(".") + 1);
+        return Character.toLowerCase(beanName.charAt(0)) + beanName.substring(1);
+    }
+
+    // Package Private Inner Classes ------------------------------------------
+
+    /**
+     * Provides a Spring bean name and page bean property setter method holder.
+     *
+     * @author Malcolm Edgar
+     */
+    static class BeanNameAndMethod {
+
+        /** The Spring bean name. */
+        protected final String beanName;
+
+        /** The page bean property setter method. */
+        protected final Method method;
+
+        /**
+         * Create a new String bean name and page setter method object.
+         *
+         * @param beanName the spring bean name
+         * @param method the page setter method for the bean
+         */
+        protected BeanNameAndMethod(String beanName, Method method) {
+            this.beanName = beanName;
+            this.method = method;
         }
     }
 

Modified: incubator/click/trunk/click/framework/src/org/apache/click/service/ConfigService.java
URL: http://svn.apache.org/viewvc/incubator/click/trunk/click/framework/src/org/apache/click/service/ConfigService.java?rev=768530&r1=768529&r2=768530&view=diff
==============================================================================
--- incubator/click/trunk/click/framework/src/org/apache/click/service/ConfigService.java (original)
+++ incubator/click/trunk/click/framework/src/org/apache/click/service/ConfigService.java Sat Apr 25 13:50:28 2009
@@ -19,6 +19,7 @@
 package org.apache.click.service;
 
 import java.lang.reflect.Field;
+import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 
@@ -250,6 +251,13 @@
     public Class getPageClass(String path);
 
     /**
+     * Return the list of configured page classes.
+     *
+     * @return the list of configured page classes
+     */
+    public List getPageClassList();
+
+    /**
      * Return Map of public fields for the given page class.
      *
      * @param pageClass the page class

Modified: incubator/click/trunk/click/framework/src/org/apache/click/service/XmlConfigService.java
URL: http://svn.apache.org/viewvc/incubator/click/trunk/click/framework/src/org/apache/click/service/XmlConfigService.java?rev=768530&r1=768529&r2=768530&view=diff
==============================================================================
--- incubator/click/trunk/click/framework/src/org/apache/click/service/XmlConfigService.java (original)
+++ incubator/click/trunk/click/framework/src/org/apache/click/service/XmlConfigService.java Sat Apr 25 13:50:28 2009
@@ -488,6 +488,23 @@
     }
 
     /**
+     * @see ConfigService#getPageClassList()
+     *
+     * @return the list of configured page classes
+     */
+    public List getPageClassList() {
+        List classList = new ArrayList(pageByClassMap.size());
+
+        Iterator i = pageByClassMap.keySet().iterator();
+        while (i.hasNext()) {
+            Class pageClass = (Class) i.next();
+            classList.add(pageClass);
+        }
+
+        return classList;
+    }
+
+    /**
      * @see ConfigService#getPageHeaders(String)
      *
      * @param path the path of the page

Propchange: incubator/click/trunk/click/lib/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Sat Apr 25 13:50:28 2009
@@ -23,3 +23,4 @@
 hibernate-2.1.8.jar
 log4j-1.2.14.jar
 hibernate-3.2.6.ga.jar
+velocity-1.6.2.jar



Mime
View raw message