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