You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@struts.apache.org by gv...@apache.org on 2006/01/16 05:52:38 UTC

svn commit: r369344 - in /struts/shale/trunk/use-cases/src: java/org/apache/shale/usecases/rolodex/ java/org/apache/shale/usecases/view/ test/org/apache/shale/usecases/rolodex/ web/WEB-INF/ web/rolodex/

Author: gvanmatre
Date: Sun Jan 15 20:52:24 2006
New Revision: 369344

URL: http://svn.apache.org/viewcvs?rev=369344&view=rev
Log:
Added some simple data table navigation components to demonstrate the new shale static remoting resource feature and Clay's malleability.

Added:
    struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/rolodex/HeaderSorter.java   (with props)
    struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/rolodex/HeaderSorterRenderer.java   (with props)
    struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/rolodex/WebPager.java   (with props)
    struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/rolodex/WebPagerRenderer.java   (with props)
    struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/rolodex/down.gif   (with props)
    struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/rolodex/next.gif   (with props)
    struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/rolodex/previous.gif   (with props)
    struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/rolodex/up.gif   (with props)
Modified:
    struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/rolodex/Rolodex.java
    struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/rolodex/dex.xml
    struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/view/Bundle.properties
    struts/shale/trunk/use-cases/src/test/org/apache/shale/usecases/rolodex/RolodexTestCase.java
    struts/shale/trunk/use-cases/src/web/WEB-INF/clay-config.xml
    struts/shale/trunk/use-cases/src/web/WEB-INF/faces-config.xml
    struts/shale/trunk/use-cases/src/web/rolodex/hrolodex.html
    struts/shale/trunk/use-cases/src/web/rolodex/rolodex.jsp
    struts/shale/trunk/use-cases/src/web/rolodex/xhrolodex.html

Added: struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/rolodex/HeaderSorter.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/rolodex/HeaderSorter.java?rev=369344&view=auto
==============================================================================
--- struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/rolodex/HeaderSorter.java (added)
+++ struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/rolodex/HeaderSorter.java Sun Jan 15 20:52:24 2006
@@ -0,0 +1,156 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.shale.usecases.rolodex;
+
+import javax.faces.component.html.HtmlOutputText;
+import javax.faces.context.FacesContext;
+import javax.faces.el.ValueBinding;
+
+public class HeaderSorter extends HtmlOutputText {
+    private String sortBy = null;
+    private boolean sortAscending = true;
+    private String ascImage = null;
+    private String descImage = null;
+
+
+    /**
+     * <p>Sets the renderer type to "org.apache.shale.HeaderSorter".</p>
+     *
+     */
+    public HeaderSorter() {
+        setRendererType("org.apache.shale.HeaderSorter");
+    }
+    
+    /**
+     * <p>Sets the family to "org.apache.shale.Sorter".</p>
+     */
+    public String getFamily() {
+       return "org.apache.shale.Sorter";
+    }
+
+    /**
+     * <p>Returns <code>true</code> if the component was selected.</p>
+     */
+    public boolean wasSelected() {
+        boolean selected = false;
+        if ((getId() != null) && getAttributes().get("defaultSort") != null) 
+            selected = (getAttributes().get("defaultSort").equals(getId()));
+        return selected;
+    }
+
+    /**
+     * <p>Restores the component's state.</p>
+     */
+    public void restoreState(FacesContext facescontext, Object obj) {
+        Object[] sobj = (Object[]) obj;
+        super.restoreState(facescontext, sobj[0]);
+        
+        sortBy = (String) sobj[1];
+        ascImage = (String) sobj[2];
+        descImage = (String) sobj[3];
+        sortAscending = ((Boolean) sobj[4]).booleanValue();
+        sobj = null;
+
+    }
+
+    /**
+     * <p>Saves the component's state.</p>
+     */
+    public Object saveState(FacesContext facescontext) {
+
+        Object aobj[] = new Object[5];
+        aobj[0] = super.saveState(facescontext);
+        aobj[1] = sortBy;
+        aobj[2] = ascImage;
+        aobj[3] = descImage;
+        aobj[4] = new Boolean(sortAscending);
+
+        return aobj;
+    }
+
+    /**
+     * <p>Returns a comma delimited list of properties to sort by.  The property names 
+     * are defined in the bean collection contained by the UIData model.</p>
+     */
+    public String getSortBy() {
+
+        if (null != sortBy)
+            return sortBy;
+        ValueBinding valuebinding = getValueBinding("sortBy");
+        if (valuebinding != null)
+            return (String) valuebinding.getValue(getFacesContext());
+        else
+            return null;
+
+    }
+
+    /**
+     * <p>Sets a comma delimited list of properties to sort by.  The property names 
+     * are defined in the bean collection contained by the UIData model.</p>
+     */    
+    public void setSortBy(String s) {
+        sortBy = s;
+    }
+
+    /**
+     * <p>Returns <code>true</code> if the model data is sorted in ascending order
+     * defined by the <code>sortBy</code> property.</p> 
+     */
+    public boolean isSortAscending() {
+        return sortAscending;
+    }
+
+    /**
+     * <p>This setter toggles the collating sequence from ascending to descending.</p>
+     */
+    public void setSortAscending(boolean b) {
+        sortAscending = b;
+    }
+
+    /**
+     * <p>Returns the acending image resource location that is relative to the
+     * context root.</p> 
+     */
+    public String getAscImage() {
+        return ascImage;
+    }
+
+    /**
+     * <p>Returns the decending image resource location that is relative to the
+     * context root.</p> 
+     */   
+    public String getDescImage() {
+        return descImage;
+    }
+
+    /**
+     * <p>Sets the acending image resource location that is relative to the
+     * context root.</p> 
+     */
+    public void setAscImage(String string) {
+        ascImage = string;
+    }
+
+    /**
+     * <p>Sets the decending image resource location that is relative to the
+     * context root.</p> 
+     */   
+    public void setDescImage(String string) {
+        descImage = string;
+    }
+
+
+}

Propchange: struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/rolodex/HeaderSorter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/rolodex/HeaderSorter.java
------------------------------------------------------------------------------
    svn:keywords = date author id rev

Added: struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/rolodex/HeaderSorterRenderer.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/rolodex/HeaderSorterRenderer.java?rev=369344&view=auto
==============================================================================
--- struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/rolodex/HeaderSorterRenderer.java (added)
+++ struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/rolodex/HeaderSorterRenderer.java Sun Jan 15 20:52:24 2006
@@ -0,0 +1,244 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shale.usecases.rolodex;
+
+import java.io.IOException;
+import java.net.URLEncoder;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import javax.faces.component.UIComponent;
+import javax.faces.component.UIData;
+import javax.faces.context.FacesContext;
+import javax.faces.context.ResponseWriter;
+import javax.faces.render.Renderer;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.shale.util.Messages;
+
+public class HeaderSorterRenderer extends Renderer {
+
+    
+    /**
+     * <p>Commons logging utility object static instance.</p>
+     */
+    private static Log log;
+    static {
+        log = LogFactory.getLog(HeaderSorterRenderer.class);
+    }
+
+    /**
+     * <p>Localized messages for this application.</p>
+     */
+    private static Messages messages =
+      new Messages("org.apache.shale.usecases.view.Bundle");
+    
+
+    /**
+     * <p>Constant used to create the query parameter that
+     * identifies the sorted column.</p>
+     */
+    private static final String SORTED_COLUMN = "s";
+
+    /**
+     * <p>Finds the parent IUData component.</p>
+     */
+    protected UIData findDataComponent(UIComponent uicomponent) {
+        return (UIData) findDataParent(uicomponent);
+    }
+
+    /**
+     * <p>Recursive method that finds the first parent Idata component.</p>
+     */
+    private UIComponent findDataParent(UIComponent uicomponent) {
+        if (uicomponent == null)
+            return null;
+        if (uicomponent instanceof UIData)
+            return uicomponent;
+        else
+            return findDataParent(uicomponent.getParent());
+    }
+
+    /**
+     * <p>Returns the base context root of the form using the
+     * view handler.</p>
+     */
+    protected String getActionStr(FacesContext context) {
+        String uri = context.getViewRoot().getViewId();
+        String url =
+            context.getApplication().getViewHandler().getActionURL(
+                context,
+                uri);
+
+        return url;
+    }
+
+    /**
+     * <p>The name of the query parameter used to control column sorting.</p>
+     */
+    protected String getSortedTag(FacesContext context, UIData data) {
+        StringBuffer clientId = new StringBuffer(data.getClientId(context));
+        clientId.append(SORTED_COLUMN);
+        return clientId.toString();
+    }
+
+    /**
+     * <p>Determines if the column was click to be sorted on.</p>
+     */
+    protected boolean wasSelected(
+        FacesContext context,
+        UIData data,
+        HeaderSorter column) {
+
+        boolean wasSelected = false;
+        Map params = context.getExternalContext().getRequestParameterMap();
+        String tag = getSortedTag(context, data);
+        if (params.containsKey(tag)) {
+            String value = (String) params.get(tag);
+            wasSelected = value.equals(column.getId());
+            column.getAttributes().put("defaultSort", value);
+
+            // toggle the sort order flag
+            column.setSortAscending(!column.isSortAscending());
+
+            value = null;
+        } else if (column.wasSelected()) {
+            wasSelected = true;
+        }
+
+        tag = null;
+        params = null;
+
+        return wasSelected;
+    }
+
+    /**
+     * <p>Initiates the component rendering.</p>
+     */
+    public void encodeBegin(FacesContext context, UIComponent component)
+        throws IOException {
+
+        if (context == null || component == null)
+            throw new NullPointerException();
+
+        if (!component.isRendered())
+            return;
+
+        ResponseWriter writer = context.getResponseWriter();
+
+        UIData data = findDataComponent(component);
+        if (data == null)
+            throw new NullPointerException(messages.getMessage("headerSorter.invalid"));
+
+        boolean wasSelected =
+            wasSelected(context, data, (HeaderSorter) component);
+
+        if (wasSelected) {
+            GenericComparator adapter =
+                new GenericComparator();
+            adapter.setSortAscending(
+                ((HeaderSorter) component).isSortAscending());
+            adapter.setSortBy(
+                ((HeaderSorter) component).getSortBy());
+
+            Collections.sort((List) data.getValue(), adapter);
+
+            adapter = null;
+            
+            writer.startElement("input", component);
+            writer.writeAttribute("type", "hidden", "type");
+            writer.writeAttribute("name", this.getSortedTag(context, data), "name");
+            writer.writeAttribute("value", ((HeaderSorter) component).getId(), "value");
+            writer.write(' ');
+        }
+
+
+        StringBuffer url = new StringBuffer(getActionStr(context));
+        url.append('?').append(getSortedTag(context, data)).append("=").append(
+            URLEncoder.encode(component.getId(), "UTF-8"));
+        writer.startElement("a", component);
+        writer.writeAttribute("href", context.getExternalContext().encodeActionURL(url.toString()), "href");
+        writer.writeText((String) ((HeaderSorter) component).getValue(), "value");
+
+        url = null;
+        writer = null;
+        data = null;
+
+        super.encodeBegin(context, component);
+    }
+
+    /**
+     * <p>Completes component rendering.</p>
+     */
+    public void encodeEnd(FacesContext context, UIComponent component)
+        throws IOException {
+
+        if (context == null || component == null)
+            throw new NullPointerException();
+
+        if (!component.isRendered())
+            return;
+
+        super.encodeEnd(context, component);
+
+        boolean wasSelected = ((HeaderSorter) component).wasSelected();
+        boolean wasSortedAscending =
+            ((HeaderSorter) component).isSortAscending();
+
+        ResponseWriter writer = context.getResponseWriter();
+
+        if (wasSelected) {
+
+            StringBuffer url =
+                new StringBuffer(
+                    context.getExternalContext().getRequestContextPath());
+
+            String title = null;
+            if (wasSortedAscending) {
+                if (((HeaderSorter) component).getAscImage() != null) {
+                    url.append(((HeaderSorter) component).getAscImage());
+                } else {
+                    url.append(messages.getMessage("headerSorter.ascImage"));
+                }
+                title = messages.getMessage("headerSorter.ascTitle");
+            } else {
+                if (((HeaderSorter) component).getDescImage() != null) {
+                    url.append(((HeaderSorter) component).getDescImage());
+                } else {
+                    url.append(messages.getMessage("headerSorter.descImage"));
+                }
+                title = messages.getMessage("headerSorter.descTitle");
+            }
+
+            writer.startElement("img", component);
+            writer.writeAttribute("border", "0", "border");
+            writer.writeAttribute("src", context.getExternalContext().encodeActionURL(url.toString()), "src");
+            writer.writeAttribute("title", title, "title");
+            writer.write(' ');
+                        
+            url = null;
+            title = null;
+
+        }
+        writer.endElement("a");
+        writer = null;
+
+    }
+    
+}

Propchange: struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/rolodex/HeaderSorterRenderer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/rolodex/HeaderSorterRenderer.java
------------------------------------------------------------------------------
    svn:keywords = date author id rev

Modified: struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/rolodex/Rolodex.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/rolodex/Rolodex.java?rev=369344&r1=369343&r2=369344&view=diff
==============================================================================
--- struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/rolodex/Rolodex.java (original)
+++ struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/rolodex/Rolodex.java Sun Jan 15 20:52:24 2006
@@ -101,6 +101,7 @@
             log.info("Switching from tab " + selectedTab + " to tab " + index);
 
         selectedTab = index;
+        contacts = null;
     }
 
     /**
@@ -335,6 +336,11 @@
     }
 
     /**
+     * <p>Caches the current contacts.</p>
+     */
+    private List contacts = null;
+    
+    /**
      * <p>
      * This is called by the data table component to return a list of
      * {@link Contact}s that belong within the selected index.
@@ -344,12 +350,14 @@
         if (log.isInfoEnabled())
             log.info("getContactsForTab()");
 
-        // find the dao cached in application scope
-        RolodexDao dao = (RolodexDao) getBean("rolodexDao");
-
-        // gets a list of contacts matching the selected tab index
-        List contacts = dao.findContactsForTab(getSelectedTab());
-
+        if (contacts == null) {
+            // find the dao cached in application scope
+            RolodexDao dao = (RolodexDao) getBean("rolodexDao");
+            
+            // gets a list of contacts matching the selected tab index
+            contacts = dao.findContactsForTab(getSelectedTab());
+        }
+        
         return contacts;
     }
 
@@ -418,6 +426,7 @@
             RolodexDao dao = (RolodexDao) getBean("rolodexDao");
             dao.deleteContact(getSelectedContact());
             setSelectedContact(null);
+            contacts = null;
         }
 
         return "rolodex$test";

Added: struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/rolodex/WebPager.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/rolodex/WebPager.java?rev=369344&view=auto
==============================================================================
--- struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/rolodex/WebPager.java (added)
+++ struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/rolodex/WebPager.java Sun Jan 15 20:52:24 2006
@@ -0,0 +1,206 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.shale.usecases.rolodex;
+
+import javax.faces.component.UIOutput;
+import javax.faces.context.FacesContext;
+import javax.faces.el.ValueBinding;
+
+public class WebPager extends UIOutput {
+    
+    private String prevPageStyleClass = null;
+    private String prevImage = null;
+    private String nextPageStyleClass = null;
+    private String nextImage = null;
+    private String captionStyleClass = null;
+    private String pageLinksStyleClass = null;
+
+    /**
+     * <p>Sets the renderer type to "org.apache.shale.WebPager".</p>
+     */
+    public WebPager() {
+        setRendererType("org.apache.shale.WebPager");
+    }
+
+    /**
+     * <p>Saves the components state.</p>
+     */
+    public Object saveState(FacesContext facescontext) {
+        Object aobj[] = new Object[5];
+        aobj[0] = super.saveState(facescontext);
+        aobj[1] = prevPageStyleClass;
+        aobj[2] = nextPageStyleClass;
+        aobj[3] = pageLinksStyleClass;
+        aobj[4] = captionStyleClass;
+        return ((Object) (aobj));
+    }
+
+    /**
+     * <p>Restores the components state.</p>
+     */
+    public void restoreState(FacesContext facescontext, Object obj) {
+        Object aobj[] = (Object[]) obj;
+        super.restoreState(facescontext, aobj[0]);
+        prevPageStyleClass = (String) aobj[1];
+        nextPageStyleClass = (String) aobj[2];
+        pageLinksStyleClass = (String) aobj[3];
+        captionStyleClass = (String) aobj[4];
+    };
+
+    
+    /**
+     * <p>Returns the pager captionStyleClass attribute.</p>
+     */
+    public String getCaptionStyleClass() {
+        if (null != captionStyleClass)
+            return captionStyleClass;
+        ValueBinding valuebinding = getValueBinding("captionStyleClass");
+        if (valuebinding != null)
+            return (String) valuebinding.getValue(getFacesContext());
+        else
+            return null;
+    }
+
+       
+    /**
+     * <p>Sets the pager captionStyleClass attribute.</p>
+     */
+    public void setCaptionStyleClass(String captionStyleClass) {
+       this.captionStyleClass = captionStyleClass;
+    }
+
+    
+    /**
+     * <p>Returns the pager pageLinksStyleClass attribute.</p>
+     */
+    public String getPageLinksStyleClass() {
+        if (null != pageLinksStyleClass)
+            return pageLinksStyleClass;
+        ValueBinding valuebinding = getValueBinding("pageLinksStyleClass");
+        if (valuebinding != null)
+            return (String) valuebinding.getValue(getFacesContext());
+        else
+            return null;
+    }
+    
+   
+    /**
+     * <p>Sets the pager pageLinksStyleClass attribute.</p>
+     */
+    public void setPageLinksStyleClass(String pageLinksStyleClass) {
+       this.pageLinksStyleClass = pageLinksStyleClass;
+    }
+
+
+    
+    /**
+     * <p>Returns the pager prevPageStyleClass attribute.</p>
+     */
+    public String getPrevPageStyleClass() {
+        if (null != prevPageStyleClass)
+            return prevPageStyleClass;
+        ValueBinding valuebinding = getValueBinding("prevPageStyleClass");
+        if (valuebinding != null)
+            return (String) valuebinding.getValue(getFacesContext());
+        else
+            return null;
+    }
+
+    
+    /**
+     * <p>Sets the pager prevPageStyleClass attribute.</p>
+     */
+    public void setPrevPageStyleClass(String s) {
+        prevPageStyleClass = s;
+    }
+
+    /**
+     * <p>Returns the pager nextPageStyleClass attribute.</p>
+     */
+    public String getNextPageStyleClass() {
+        if (null != nextPageStyleClass)
+            return nextPageStyleClass;
+        ValueBinding valuebinding = getValueBinding("nextPageStyleClass");
+        if (valuebinding != null)
+            return (String) valuebinding.getValue(getFacesContext());
+        else
+            return null;
+    }
+
+    /**
+     * <p>Sets the pager nextPageStyleClass attribute.</p>
+     */
+    public void setNextPageStyleClass(String s) {
+        nextPageStyleClass = s;
+    }
+
+    
+    /**
+     * <p>Sets the pager prevImage attribute.</p>
+     */
+    public void setPrevImage(String s) {
+        prevImage = s;
+    }
+
+    /**
+     * <p>Returns the pager prevImage attribute.</p>
+     */
+    public String getPrevImage() {
+        if (null != prevImage)
+            return prevImage;
+        ValueBinding valuebinding = getValueBinding("prevImage");
+        if (valuebinding != null)
+            return (String) valuebinding.getValue(getFacesContext());
+        else
+            return null;
+    }
+   
+    /**
+     * <p>Sets the pager nextImage attribute.</p>
+     */
+    public void setNextImage(String s) {
+        nextImage = s;
+    }
+
+    /**
+     * <p>Returns the pager nextImage attribute.</p>
+     */
+    public String getNextImage() {
+        if (null != nextImage)
+            return nextImage;
+        ValueBinding valuebinding = getValueBinding("nextImage");
+        if (valuebinding != null)
+            return (String) valuebinding.getValue(getFacesContext());
+        else
+            return null;
+    }
+    
+      
+    
+    /**
+     * <p>Returns the component's family to "org.apache.shale.Pager".</p>
+     */
+    public String getFamily() {
+        return "org.apache.shale.Pager";
+    }
+
+    /**
+     * <p>The pager component renders children.</p>
+     */
+    public boolean getRendersChildren() {
+        return true;
+    }
+}
\ No newline at end of file

Propchange: struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/rolodex/WebPager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/rolodex/WebPager.java
------------------------------------------------------------------------------
    svn:keywords = date author id rev

Added: struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/rolodex/WebPagerRenderer.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/rolodex/WebPagerRenderer.java?rev=369344&view=auto
==============================================================================
--- struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/rolodex/WebPagerRenderer.java (added)
+++ struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/rolodex/WebPagerRenderer.java Sun Jan 15 20:52:24 2006
@@ -0,0 +1,609 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shale.usecases.rolodex;
+
+import java.io.IOException;
+import java.text.DecimalFormat;
+import java.text.Format;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.faces.component.UIComponent;
+import javax.faces.component.UIData;
+import javax.faces.context.FacesContext;
+import javax.faces.context.ResponseWriter;
+import javax.faces.render.Renderer;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.shale.util.Messages;
+
+public class WebPagerRenderer extends Renderer {
+
+       
+    /**
+     * <p>Commons logging utility object static instance.</p>
+     */
+    private static Log log;
+    static {
+        log = LogFactory.getLog(WebPagerRenderer.class);
+    }
+
+    /**
+     * <p>Localized messages for this application.</p>
+     */
+    private static Messages messages =
+      new Messages("org.apache.shale.usecases.view.Bundle");
+    
+    /**
+     * <p>Constant used to create the selected page query parameter.</p>
+     */
+    private static final String PAGER_SIMPLE_NUMBERLIST = "p";
+
+    /**
+     * <p>This basic component doesn't use javascript for 
+     * navigation.  This means that the decode logic is in 
+     * the encode/rendering phase.</p>
+     */
+    public void decode(FacesContext context, UIComponent pager) {
+        if (log.isTraceEnabled())
+            log.trace("decode(FacesContext, UIComponent)");
+    }
+
+    /**
+     * <p>Locates a parent UIData component, decodes the selected 
+     * page query parameter and advances the first row of the 
+     * UIData component based on the selected page.</p>
+     */
+    public void encodeEnd(FacesContext context, UIComponent pager)
+        throws IOException {
+
+        if (context == null || pager == null)
+            throw new NullPointerException();
+
+        if (!pager.isRendered())
+            return;
+
+        UIData data = this.findDataComponent(pager);
+        if (data == null)
+            throw new NullPointerException(messages.getMessage("webPager.invalid"));
+
+        int startIndex = getPageStartIndex(context, data);
+        data.setFirst(Math.max(startIndex, 0));
+
+        ResponseWriter writer = context.getResponseWriter();
+
+        writer.startElement("table",pager);
+        writer.writeAttribute("border", "0", "border");
+
+        writer.startElement("tr",pager);
+        writer.startElement("td", pager);
+        writer.writeAttribute("colspan", "3", "colspan");
+        writePageCaption(context, data, pager);
+        writer.endElement("td");
+        writer.endElement("tr");
+
+        writer.startElement("tr",pager);
+        writer.startElement("td", pager);
+        writePrevPageLink(context, data, pager);
+        writer.endElement("td");
+        writer.startElement("td", pager);               
+        writePageLinks(context, data, pager);
+        writer.endElement("td");
+        writer.startElement("td", pager);               
+        writeNextPageLink(context, data, pager);
+        writer.endElement("td");
+        writer.endElement("tr");
+        writer.endElement("table");
+        writePageIndex(context, data, pager);
+        
+        writer = null;
+        data = null;
+    }
+
+    
+    /**
+     * <p>Writes the previous page link.</p>
+     */
+    protected void writePrevPageLink(
+        FacesContext context,
+        UIData data,
+        UIComponent pager)
+        throws IOException {
+
+        ResponseWriter writer = context.getResponseWriter();
+        PageInfo p = prevPage(context, data);
+
+        String styleClass = (String) pager.getAttributes().get("prevPageStyleClass");
+
+        writer.startElement("span", pager);
+        
+        if (styleClass != null) {
+            writer.writeAttribute("class", styleClass, "prevPageStyleClass");
+        }
+        if (p != null) {
+
+            Object[] params = {new Integer(p.getRowsOnPage())};
+            String prevLabel = messages.getMessage("webPager.prevTitle", params);
+
+            StringBuffer url = new StringBuffer(getActionStr(context));
+            url.append('?').append(getPageTag(context, data)).append('=');
+            url.append(p.getPage());
+
+            writer.startElement("a", pager);
+            writer.writeAttribute("href", context.getExternalContext().encodeActionURL(url.toString()), "href");
+            writer.writeAttribute("title", prevLabel, "title");
+            
+            url.setLength(0);
+            url.append(getActionStr(context));
+            url.setLength(url.indexOf("/", 1));
+            String prevImage = (String) pager.getAttributes().get("prevImage");
+            
+            if (prevImage == null)
+               prevImage = messages.getMessage("webPager.prevImage");
+            
+            url.append(prevImage);
+            writer.startElement("img", pager);
+            writer.writeAttribute("src", context.getExternalContext().encodeActionURL(url.toString()), "scr");
+            
+            
+            writer.endElement("a");
+            
+            url = null;
+
+        }
+
+        writer.endElement("span");
+        p = null;
+        writer = null;
+        styleClass = null;
+
+    }
+
+    
+    /**
+     * <p>Renders a hidden input field that keeps track of the current page.</p>
+     */
+    protected void writePageIndex(FacesContext context, UIData data, UIComponent pager) throws IOException {
+        ResponseWriter writer = context.getResponseWriter();
+        int page = getPageIndex(context, data);
+        writer.startElement("input", pager);
+        writer.writeAttribute("name", getPageTag(context, data), "name");
+        writer.writeAttribute("type", "hidden", "type");
+        writer.writeAttribute("value", Integer.toString(page), "value");
+        writer.endElement("input");    
+    }
+    
+    /**
+     * <p>Writes a pager caption documenting the total model rows, current page and total pages.</p>
+     */
+    protected void writePageCaption(FacesContext context, UIData data, UIComponent pager) throws IOException {
+        ResponseWriter writer = context.getResponseWriter();
+        
+        Object[] params = new Object[3];
+        params[0] = new Integer(data.getRowCount());
+        params[1] = new Integer(getPageIndex(context, data));
+        params[2] = new Integer(getPages(data));
+        
+        String caption = messages.getMessage("webPager.defaultcaption", params);
+        
+        String styleClass = (String) pager.getAttributes().get("captionStyleClass");
+
+        writer.startElement("span", pager);
+        
+        if (styleClass != null) {
+            writer.writeAttribute("class", styleClass, "pageCaptionStyleClass");
+        }
+        
+        
+        writer.writeText(caption, "webPager.defaultcaption");
+
+        writer.endElement("span");
+        writer = null;
+        styleClass = null;
+
+    }
+    
+    /**
+     * <p>The first ten pages are displayed as individual page links.  
+     * The remainder of page links are displayed in increments of ten.</p>
+     */
+    protected void writePageLinks(FacesContext context, UIData data, UIComponent pager)
+        throws IOException {
+
+        ResponseWriter writer = context.getResponseWriter();
+        Format fmt = new DecimalFormat("#,##0");
+
+        String styleClass = (String) pager.getAttributes().get("pageLinksStyleClass");
+
+        writer.startElement("span", pager);
+
+        if (styleClass != null) {
+            writer.writeAttribute("class", styleClass, "pageLinksStyleClass");
+        }
+        
+        StringBuffer url = new StringBuffer(getActionStr(context));
+        url.append('?').append(getPageTag(context, data)).append('=');
+        int urlLen = url.length();
+
+        Iterator pi = iterator(context, data);
+        while (pi.hasNext()) {
+
+            PageInfo p = (PageInfo) pi.next();
+
+            String ps = fmt.format(new Integer(p.getPage()));
+            if (p.isSelected()) {
+                writer.write(' ');
+                writer.startElement("b", pager);
+                writer.writeText(ps, "page");
+                writer.endElement("b");
+                writer.write(' ');
+            } else {
+
+                url.setLength(urlLen);
+                url.append(p.getPage());
+
+                writer.write(' ');
+                writer.startElement("a", pager);
+                writer.writeAttribute("href", context.getExternalContext().encodeActionURL(url.toString()), "href");
+                writer.writeAttribute("title", 
+                         messages.getMessage("webPager.linkTitle", new Object[] {new Integer(p.getPage())}), "title");
+                writer.writeText(ps, "page");
+                writer.endElement("a");
+                writer.write(' ');
+            }
+            ps = null;
+            p = null;
+        }
+
+        writer.endElement("span");
+
+        pi = null;
+        url = null;
+        fmt = null;
+        writer = null;
+    }
+
+    /**
+     * <p>Generates the next page link.</p>
+     */
+    protected void writeNextPageLink(FacesContext context, UIData data, UIComponent pager)
+        throws IOException {
+
+        ResponseWriter writer = context.getResponseWriter();
+        PageInfo p = nextPage(context, data);
+
+
+        String styleClass = (String) pager.getAttributes().get("nextPageStyleClass");
+
+        writer.startElement("span", pager);
+        
+        if (styleClass != null) {
+            writer.writeAttribute("class", styleClass, "nextPageStyleClass");
+        }
+        if (p != null) {
+            Object[] params = {new Integer(p.getRowsOnPage())};
+            String nextLabel = messages.getMessage("webPager.nextTitle", params);
+            
+            StringBuffer url = new StringBuffer(getActionStr(context));
+            url.append('?').append(getPageTag(context, data)).append('=');
+            url.append(p.getPage());
+
+            writer.startElement("a", pager);
+            writer.writeAttribute("href", context.getExternalContext().encodeActionURL(url.toString()), "href");
+            writer.writeAttribute("title", nextLabel, "title");
+            
+            url.setLength(0);
+            url.append(getActionStr(context));
+            url.setLength(url.indexOf("/", 1));
+            String nextImage = (String) pager.getAttributes().get("nextImage");
+            
+            if (nextImage == null)
+               nextImage = messages.getMessage("webPager.nextImage");
+            
+            url.append(nextImage);
+            writer.startElement("img", pager);
+            writer.writeAttribute("src", context.getExternalContext().encodeActionURL(url.toString()), "scr");
+            
+            
+            url = null;
+
+        }
+
+        writer.endElement("span");
+        p = null;
+        writer = null;
+        styleClass = null;
+
+    }
+
+    /**
+     * <p>Determines the base URL by calling on the view handler.</p>  
+     */
+    protected String getActionStr(FacesContext context) {
+        String uri = context.getViewRoot().getViewId();
+        String url =
+            context.getApplication().getViewHandler().getActionURL(
+                context,
+                uri);
+
+        return url;
+    }
+
+    /**
+     * <p>Returns the query parameter tag based on the parent UIData 
+     * component.</p>
+     */
+    protected String getPageTag(FacesContext context, UIData data) {
+        StringBuffer clientId = new StringBuffer(data.getClientId(context));
+        clientId.append(PAGER_SIMPLE_NUMBERLIST);
+        return clientId.toString();
+    }
+
+    /**
+     * <p>Returns the selected page index.  This would be done in the decode method if 
+     * this control was not scriptless.</p>
+     */
+    protected int getPageIndex(FacesContext context, UIData data) {
+
+        int defaultPage = 1;
+        int page = 0;
+        try {
+            Map params = context.getExternalContext().getRequestParameterMap();
+            String tag = getPageTag(context, data);
+            if (params.containsKey(tag)) {
+                page = Integer.parseInt((String) params.get(tag));
+            } else {
+                page = getCurrentPage(data) + 1;
+            }
+            tag = null;
+            params = null;
+        } catch (NumberFormatException e) {
+            e.printStackTrace();
+        }
+
+        return Math.min(Math.max(page, defaultPage), getPages(data));
+    }
+
+    /**
+     * <p>Returns the current page based on the UIData component's
+     * state.</p>
+     */
+    protected int getCurrentPage(UIData uidata) {
+        if (uidata == null)
+            return 0;
+        int i = uidata.getRows();
+        if (i <= 0)
+            return 0;
+        else
+            return ((int) (uidata.getFirst() / i));
+    }
+    
+    /**
+     * <p>Looks for the first data component parent.</p>
+     */
+    protected UIData findDataComponent(UIComponent uicomponent) {
+        return (UIData) findDataParent(uicomponent);
+    }
+
+    /**
+     * <p>Recursively looks up the component tree for a parent UIData component.</p>
+     */
+    private UIComponent findDataParent(UIComponent uicomponent) {
+        if (uicomponent == null)
+            return null;
+        if (uicomponent instanceof UIData)
+            return uicomponent;
+        else
+            return findDataParent(uicomponent.getParent());
+    }
+
+    /**
+     * <p>Returns the rows per page of the UIData component.
+     * The value must be five or more.</b> 
+     */
+    protected int getRowsPerPage(UIData data) {
+        int rowsPerPage = Math.max(data.getRows(), 5);
+        return rowsPerPage;
+    }
+
+    /**
+     * <p>Returns the starting row within the UIData's model based
+     * on the selected page index, the total rows the model has and 
+     * the rows per page.</p> 
+     */
+    protected int getPageStartIndex(FacesContext context, UIData data) {
+        return getPageStartIndex(getPageIndex(context, data), context, data);
+    }
+
+    /**
+     * <p>Returns the starting row within the UIData's model based
+     * on the selected page index, the total rows the model has and 
+     * the rows per page.</p> 
+     */
+    protected int getPageStartIndex(
+        int page,
+        FacesContext context,
+        UIData data) {
+        int rowsPerPage = getRowsPerPage(data);
+        
+        return (page - 1) * rowsPerPage;
+    }
+
+    /**
+     * <p>Returns the ending row index displayed by the UIData component.</p>
+     */
+    protected int getPageEndIndex(FacesContext context, UIData data) {
+        return getPageEndIndex(getPageIndex(context, data), context, data);
+    }
+
+    /**
+     * <p>Returns the ending row index displayed by the UIData component.</p>
+     */
+    protected int getPageEndIndex(
+        int page,
+        FacesContext context,
+        UIData data) {
+        int endPageIndex =
+            (getPageStartIndex(page, context, data) + getRowsPerPage(data)) - 1;
+        return Math.min(endPageIndex, (data.getRowCount() - 1));
+    }
+
+    /**
+     * <p>Returns the total rows on the selected page.</p> 
+     */
+    protected int getRowsOnPage(int page, FacesContext context, UIData data) {
+        return (
+            getPageEndIndex(page, context, data)
+                - getPageStartIndex(page, context, data)
+                + 1);
+    }
+
+    /**
+     * <p>Returns the total number of pages based on the size of the model's set
+     * and the total rows displayed.</p>
+     */
+    protected int getPages(UIData data) {
+        int pages = 0;
+        int rowCount = data.getRowCount();
+        int rowsPerPage = getRowsPerPage(data);
+        try {
+            pages =
+                new java
+                    .math
+                    .BigDecimal(rowCount)
+                    .divide(
+                        new java.math.BigDecimal(rowsPerPage),
+                        0,
+                        java.math.BigDecimal.ROUND_UP)
+                    .intValue();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return pages;
+    }
+
+    /**
+     * <p>Returns PageInfo used to render the previous page links.</p> 
+     */
+    protected PageInfo prevPage(FacesContext context, UIData data) {
+        int pageIndex = getPageIndex(context, data);
+
+        if (pageIndex > 1) {
+            int rowsOnPage = getRowsOnPage(pageIndex - 1, context, data);
+            return new PageInfo(pageIndex - 1, pageIndex, rowsOnPage);
+        }
+        return null;
+    }
+
+    /**
+     * <p>Returns a PageInfo Iterator used to render the individual page
+     * links.</p>
+     */
+    protected Iterator iterator(FacesContext context, UIData data) {
+        return new PageInfoIterator(
+            getPageIndex(context, data),
+            getPages(data));
+    }
+
+    /**
+     * <p>Returns PageInfo that defines the next link.</p> 
+     */
+    protected PageInfo nextPage(FacesContext context, UIData data) {
+        int pageIndex = getPageIndex(context, data);
+        if (data.getRowCount() > data.getRows() && getPages(data) > pageIndex) {
+            int rowsOnPage = getRowsOnPage(pageIndex + 1, context, data);
+            return new PageInfo(pageIndex + 1, pageIndex, rowsOnPage);
+        }
+        return null;
+    }
+
+    private class PageInfo {
+
+        private int page = 0;
+        private boolean selected = false;
+        private int rows = 0;
+
+        public PageInfo(int nextIndex, int pageIndex, int rowsOnPage) {
+            this(nextIndex, pageIndex);
+            rows = rowsOnPage;
+        }
+
+        public PageInfo(int nextIndex, int pageIndex) {
+            page = nextIndex;
+            selected = (pageIndex == nextIndex);
+        }
+
+        public int getPage() {
+            return page;
+        }
+
+        public boolean isSelected() {
+            return selected;
+        }
+
+        public int getRowsOnPage() {
+            return rows;
+        }
+
+    }
+
+    private class PageInfoIterator implements Iterator {
+
+        private int pages = 0;
+        private int pageIndex = 0;
+        private int startWindow = 0;
+        private int endWindow = 0;
+        private int index = 0;
+
+        public PageInfoIterator(int pageIndex, int pages) {
+            this.pages = pages;
+            this.pageIndex = Math.min(pageIndex, pages);
+            startWindow = (int) ((int) (.1 * (this.pageIndex - 1)) * 10);
+            endWindow = Math.min(startWindow + 10, pages);
+
+        }
+
+        public boolean hasNext() {
+            return (pages > 1) && (index < pages);
+        }
+
+        public Object next() {
+
+            // if the index is within the window, increment by one; otherwise by 10
+            if ((index >= startWindow) && (index < endWindow))
+                index++;
+            else
+                index += 10;
+
+            return new WebPagerRenderer.PageInfo(index, pageIndex);
+        }
+
+        public void remove() {
+        }
+
+    }
+
+    /**
+     * <p>Delegates to the super implementation.</p>
+     */
+    public void encodeBegin(FacesContext context, UIComponent uicomponent)
+        throws IOException {
+        super.encodeBegin(context, uicomponent);
+    }
+
+}

Propchange: struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/rolodex/WebPagerRenderer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/rolodex/WebPagerRenderer.java
------------------------------------------------------------------------------
    svn:keywords = date author id rev

Modified: struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/rolodex/dex.xml
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/rolodex/dex.xml?rev=369344&r1=369343&r2=369344&view=diff
==============================================================================
--- struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/rolodex/dex.xml (original)
+++ struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/rolodex/dex.xml Sun Jan 15 20:52:24 2006
@@ -110,6 +110,68 @@
          <country>US</country>
       </businessAddress>           
    </contact>
+
+   <contact>
+      <name>Adam, Frank</name>
+      <email>frank.adam@xys.net</email>
+      <residentialPhone>(720) 792-0774</residentialPhone>
+      <businessPhone>(720) 792-0775</businessPhone>
+   </contact>
+
+   <contact>
+      <name>Abe, Jones</name>
+      <email>Abe.Jones@xyz.net</email>
+   </contact>
+
+   <contact>
+      <name>Abbie, Smith</name>
+      <email>abbie.smith@xyz.net</email>
+   </contact>
+
+   <contact>
+      <name>Ace, Ventura</name>
+      <email>ace@pet-detective.net</email>
+   </contact>
+
+   <contact>
+      <name>Ajay, Howard</name>
+      <email>ajay@bluebird.net</email>
+   </contact>
+
+   <contact>
+      <name>Ace Hardware</name>
+      <email>ace@acehardware.com</email>
+      <residentialPhone></residentialPhone>
+      <businessPhone></businessPhone>
+      <residentialAddress>
+         <street1></street1>
+         <street2></street2>
+         <city></city>
+         <state></state>
+         <zip></zip>
+      </residentialAddress>     
+      <businessAddress>
+         <street1>9579 S University Blvd Ste </street1>
+         <street2></street2>
+         <city>Highlands Ranch</city>
+         <state>CO</state>
+         <zip>80126</zip>
+         <province></province>
+         <country></country>
+      </businessAddress>           
+   </contact>
+
+
+   <contact>
+      <name>Alice, Tucker</name>
+      <email>atucker@hotmail.com</email>
+   </contact>
+   
+   <contact>
+      <name>Adin, Brown</name>
+      <email>abrown@comcast.net</email>
+   </contact>
+
    
    <contact>
       <name>Barker, Russell R and Associates PC</name>

Added: struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/rolodex/down.gif
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/rolodex/down.gif?rev=369344&view=auto
==============================================================================
Binary file - no diff available.

Propchange: struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/rolodex/down.gif
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/rolodex/next.gif
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/rolodex/next.gif?rev=369344&view=auto
==============================================================================
Binary file - no diff available.

Propchange: struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/rolodex/next.gif
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/rolodex/previous.gif
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/rolodex/previous.gif?rev=369344&view=auto
==============================================================================
Binary file - no diff available.

Propchange: struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/rolodex/previous.gif
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/rolodex/up.gif
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/rolodex/up.gif?rev=369344&view=auto
==============================================================================
Binary file - no diff available.

Propchange: struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/rolodex/up.gif
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Modified: struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/view/Bundle.properties
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/view/Bundle.properties?rev=369344&r1=369343&r2=369344&view=diff
==============================================================================
--- struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/view/Bundle.properties (original)
+++ struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/view/Bundle.properties Sun Jan 15 20:52:24 2006
@@ -179,3 +179,20 @@
 rolodex.button.new=New Contact
 rolodex.button.save=Save Contact
 rolodex.button.delete=Delete Contact
+
+#WebPager Renderer
+webPager.invalid=The component, WebPager, must be nested within a dataTable component.
+webPager.prevTitle=Previous {0, number, #,##0}
+webPager.nextTitle=Next {0, number, #,##0}
+webPager.linkTitle=Page {0, number, #,##0}
+webPager.defaultcaption=Found {0, number, #,##0} matching record(s).  Viewing page {1, number, #,##0} of {2, number, #,##0}.
+webPager.prevImage=/static/org/apache/shale/usecases/rolodex/previous.gif.faces
+webPager.nextImage=/static/org/apache/shale/usecases/rolodex/next.gif.faces
+
+
+headerSorter.invalid=The component, HeaderSorter, must be nested within a dataTable component.
+headerSorter.ascTitle=Sorted Ascending 
+headerSorter.descTitle=Sorted Descending
+headerSorter.ascImage=/static/org/apache/shale/usecases/rolodex/up.gif.faces
+headerSorter.descImage=/static/org/apache/shale/usecases/rolodex/down.gif.faces
+

Modified: struts/shale/trunk/use-cases/src/test/org/apache/shale/usecases/rolodex/RolodexTestCase.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/use-cases/src/test/org/apache/shale/usecases/rolodex/RolodexTestCase.java?rev=369344&r1=369343&r2=369344&view=diff
==============================================================================
--- struts/shale/trunk/use-cases/src/test/org/apache/shale/usecases/rolodex/RolodexTestCase.java (original)
+++ struts/shale/trunk/use-cases/src/test/org/apache/shale/usecases/rolodex/RolodexTestCase.java Sun Jan 15 20:52:24 2006
@@ -122,12 +122,12 @@
     public void testContactsForTab() {
 
         // number of contacts per page
-        int[] knownGoodState = { 4, 1, 0, 0, 0, 0, 0, 0, 0 };
+        int[] knownGoodState = {12, 1, 0, 0, 0, 0, 0, 0, 0 };
 
         for (int i = 0; i < RolodexDao.TAB_INDEX.length; i++) {
             viewController.setSelectedTab(i);
             List contacts = viewController.getContactsForTab();
-            assertEquals("contacts on page", contacts.size(), knownGoodState[i]);
+            assertEquals("contacts on page", knownGoodState[i], contacts.size());
         }
 
     }

Modified: struts/shale/trunk/use-cases/src/web/WEB-INF/clay-config.xml
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/use-cases/src/web/WEB-INF/clay-config.xml?rev=369344&r1=369343&r2=369344&view=diff
==============================================================================
--- struts/shale/trunk/use-cases/src/web/WEB-INF/clay-config.xml (original)
+++ struts/shale/trunk/use-cases/src/web/WEB-INF/clay-config.xml Sun Jan 15 20:52:24 2006
@@ -24,10 +24,30 @@
 
 <view>
 	
+  <component jsfid="headerSorter" componentType="org.apache.shale.HeaderSorter">
+      <attributes>
+        <set name="sortBy" bindingType="VB"/>
+        <set name="ascImage" bindingType="VB"/>
+        <set name="descImage" bindingType="VB"/>
+        <set name="isFocus" bindingType="None"/>
+        <set name="value" bindingType="VB"/>
+      </attributes>  
+  </component>	
+	
+  <component jsfid="webPager" componentType="org.apache.shale.WebPager"> 
+      <attributes>
+        <set name="prevPageStyleClass" bindingType="VB" value="linkPrev"/>
+        <set name="pageLinksStyleClass" bindingType="VB" value="links"/>
+        <set name="nextPageStyleClass" bindingType="VB" value="linkNext"/>
+        <set name="captionStyleClass" bindingType="VB" value="caption"/>
+      </attributes>  
+  </component>
+	
   <component jsfid="nameColumn" extends="column" id="name">
-    <element renderId="1" jsfid="outputText" facetName="header">
+    <element renderId="1" jsfid="headerSorter" facetName="header">
       <attributes>
         <set name="value" value="#{messages['rolodex.contactTable.nameColumn.title']}" />
+        <set name="sortBy" value="name"/>
       </attributes>
     </element> 
        
@@ -52,13 +72,15 @@
     <attributes>
       <set name="value" value="#{@managed-bean-name.contactsForTab}"/>
       <set name="var"   value="e"/>
-      <set name="rows"  value="100"/> 
+      <set name="rows"  value="5"/> 
       <set name="first"  value="0"/> 
       <set name="styleClass" value="contacts"/>
       <set name="headerClass" value="contactsHeader"/>
       <set name="rowClasses" value="contactsRow1, contactsRow2"/>
       
     </attributes>
+    
+    <element renderId="0" jsfid="webPager" facetName="header"/>    
     <element renderId="1" jsfid="nameColumn"/>
   </component>
 

Modified: struts/shale/trunk/use-cases/src/web/WEB-INF/faces-config.xml
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/use-cases/src/web/WEB-INF/faces-config.xml?rev=369344&r1=369343&r2=369344&view=diff
==============================================================================
--- struts/shale/trunk/use-cases/src/web/WEB-INF/faces-config.xml (original)
+++ struts/shale/trunk/use-cases/src/web/WEB-INF/faces-config.xml Sun Jan 15 20:52:24 2006
@@ -662,6 +662,38 @@
         <value>#{param.selectedName}</value>
     </managed-property>
   </managed-bean>
+
+
+   <component>
+      <description>Simple navigation component for a data table component.</description>
+      <component-type>org.apache.shale.WebPager</component-type>
+      <component-class>org.apache.shale.usecases.rolodex.WebPager</component-class>
+   </component>	
+
+   <render-kit>		
+      <renderer>
+         <description>Renderer for a simple page navigation data table component.</description>
+         <component-family>org.apache.shale.Pager</component-family>
+         <renderer-type>org.apache.shale.WebPager</renderer-type>
+         <renderer-class>org.apache.shale.usecases.rolodex.WebPagerRenderer</renderer-class>
+      </renderer>
+   </render-kit>
+  
+   <component>
+      <description>Simple column sorter component for a data table component.</description>
+      <component-type>org.apache.shale.HeaderSorter</component-type>
+      <component-class>org.apache.shale.usecases.rolodex.HeaderSorter</component-class>
+   </component>	
+
+   <render-kit>		
+      <renderer>
+         <description>Renderer for a simple column sorter data table component.</description>
+         <component-family>org.apache.shale.Sorter</component-family>
+         <renderer-type>org.apache.shale.HeaderSorter</renderer-type>
+         <renderer-class>org.apache.shale.usecases.rolodex.HeaderSorterRenderer</renderer-class>
+      </renderer>
+   </render-kit>
+  
 
 
 <!-- DEPRECATED - see profile$logic below -->

Modified: struts/shale/trunk/use-cases/src/web/rolodex/hrolodex.html
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/use-cases/src/web/rolodex/hrolodex.html?rev=369344&r1=369343&r2=369344&view=diff
==============================================================================
--- struts/shale/trunk/use-cases/src/web/rolodex/hrolodex.html (original)
+++ struts/shale/trunk/use-cases/src/web/rolodex/hrolodex.html Sun Jan 15 20:52:24 2006
@@ -4,7 +4,28 @@
 <title>#{messages['usecases.rolodex2']}</title>
 
 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
-<style type="text/css" media="screen">
+<style type="text/css" media="screen">
+
+.linkPrev {
+	text-align: left; 
+	color: black; 
+	font-family: arial; font-size: 8pt
+}
+.linkNext {
+	text-align: right; 
+	color: black; 
+	font-family: arial; font-size: 8pt
+}
+.links {
+	text-align: center; 
+	color: black; 
+	font-family: arial; font-size: 8pt
+}
+.caption {
+	text-align: center; 
+	color: #99CC66; 
+	font-family: arial; font-size: 8pt
+}
 body {
 	margin : 10px;
 	font: Verdana, Helvetica, Arial;

Modified: struts/shale/trunk/use-cases/src/web/rolodex/rolodex.jsp
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/use-cases/src/web/rolodex/rolodex.jsp?rev=369344&r1=369343&r2=369344&view=diff
==============================================================================
--- struts/shale/trunk/use-cases/src/web/rolodex/rolodex.jsp (original)
+++ struts/shale/trunk/use-cases/src/web/rolodex/rolodex.jsp Sun Jan 15 20:52:24 2006
@@ -9,7 +9,29 @@
 <title>Rolodex Example Using Clay</title>
 
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
-<style type="text/css" media="screen">
+<style type="text/css" media="screen">
+
+.linkPrev {
+	text-align: left; 
+	color: black; 
+	font-family: arial; font-size: 8pt
+}
+.linkNext {
+	text-align: right; 
+	color: black; 
+	font-family: arial; font-size: 8pt
+}
+.links {
+	text-align: center; 
+	color: black; 
+	font-family: arial; font-size: 8pt
+}
+.caption {
+	text-align: center; 
+	color: #99CC66; 
+	font-family: arial; font-size: 8pt
+}
+
 body {
 	margin : 10px;
 	font: Verdana, Helvetica, Arial;

Modified: struts/shale/trunk/use-cases/src/web/rolodex/xhrolodex.html
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/use-cases/src/web/rolodex/xhrolodex.html?rev=369344&r1=369343&r2=369344&view=diff
==============================================================================
--- struts/shale/trunk/use-cases/src/web/rolodex/xhrolodex.html (original)
+++ struts/shale/trunk/use-cases/src/web/rolodex/xhrolodex.html Sun Jan 15 20:52:24 2006
@@ -4,7 +4,28 @@
 <title>#{messages['usecases.rolodex3']}</title>
 
 <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
-<style type="text/css" media="screen">
+<style type="text/css" media="screen">
+
+.linkPrev {
+	text-align: left; 
+	color: black; 
+	font-family: arial; font-size: 8pt
+}
+.linkNext {
+	text-align: right; 
+	color: black; 
+	font-family: arial; font-size: 8pt
+}
+.links {
+	text-align: center; 
+	color: black; 
+	font-family: arial; font-size: 8pt
+}
+.caption {
+	text-align: center; 
+	color: #99CC66; 
+	font-family: arial; font-size: 8pt
+}
 body {
 	margin : 10px;
 	font: Verdana, Helvetica, Arial;
@@ -121,18 +142,27 @@
 <table border="0">
    <tr>
       <td rowspan="3">
-              <table jsfid="dataTable" class="contacts" value="#{@managed-bean-name.contactsForTab}" var="e" rows="100" first="0" headerClass="contactsHeader" rowClasses="contactsRow1, contactsRow2" allowBody="true">
-                  <tbody id="name" jsfid="column" class="contactsHeader" allowBody="true">
-                     <th jsfid="outputText" facetName="header"  allowBody="false" value="#{messages['rolodex.contactTable.nameColumn.title']}">
-                           Contacts
-                     </th>
-                     <tr jsfid="commandLink" value="#{e.name}" action="#{@managed-bean-name.selectContact}" immediate="true" allowBody="true">
-                          <td jsfid="param" name="selectedName" value="#{e.encodedName}" allowBody="false">
-                              <a href="#">ABC Company</a>
-                          </td>
-                     </tr> 
-                  </tbody>
-              </table>
+              <table jsfid="dataTable" class="contacts" value="#{@managed-bean-name.contactsForTab}" var="e" rows="5" first="0" headerClass="contactsHeader" rowClasses="contactsRow1, contactsRow2" allowBody="true">
+                     <caption jsfid="webPager" prevPageStyleClass="linkPrev" 
+                         pageLinksStyleClass="links" nextPageStyleClass="linkNext" 
+                         captionStyleClass="caption" facetName="header" allowBody="false">
+                         Mock Page Links 
+                     </caption>
+
+                     <tbody id="name" jsfid="column" class="contactsHeader" allowBody="true">
+                     <th jsfid="headerSorter" facetName="header"  allowBody="false" value="#{messages['rolodex.contactTable.nameColumn.title']}" sortBy="name">
+                           Contacts
+                     </th>
+                     <tr jsfid="webPager" prevPageStyleClass="linkPrev" 
+                         pageLinksStyleClass="links" nextPageStyleClass="linkNext" 
+                         captionStyleClass="caption" facetName="header"/>
+                     <tr jsfid="commandLink" value="#{e.name}" action="#{@managed-bean-name.selectContact}" immediate="true" allowBody="true">
+                          <td jsfid="param" name="selectedName" value="#{e.encodedName}" allowBody="false">
+                              <a href="#">ABC Company</a>
+                          </td>
+                     </tr> 
+                  </tbody>
+              </table>
       </td>
    </tr>
    <tr>



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
For additional commands, e-mail: dev-help@struts.apache.org