You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by jk...@apache.org on 2006/01/24 04:05:17 UTC

svn commit: r371786 [3/4] - in /jakarta/tapestry/trunk: ./ eclipse/ examples/AjaxWorkbench/ examples/AjaxWorkbench/src/ examples/AjaxWorkbench/src/config/ examples/AjaxWorkbench/src/context/ examples/AjaxWorkbench/src/context/WEB-INF/ examples/AjaxWork...

Added: jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/chart/ChartPage.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/chart/ChartPage.java?rev=371786&view=auto
==============================================================================
--- jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/chart/ChartPage.java (added)
+++ jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/chart/ChartPage.java Mon Jan 23 19:04:45 2006
@@ -0,0 +1,215 @@
+// Copyright 2004, 2005, 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.tapestry.ajaxworkbench.chart;
+
+import java.awt.Color;
+import java.awt.Paint;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.hivemind.HiveMind;
+import org.apache.tapestry.IAsset;
+import org.apache.tapestry.event.PageBeginRenderListener;
+import org.apache.tapestry.event.PageEvent;
+import org.apache.tapestry.html.BasePage;
+import org.apache.tapestry.valid.IValidationDelegate;
+import org.jCharts.Chart;
+import org.jCharts.chartData.ChartDataException;
+import org.jCharts.chartData.PieChartDataSet;
+import org.jCharts.nonAxisChart.PieChart2D;
+import org.jCharts.properties.ChartProperties;
+import org.jCharts.properties.LegendAreaProperties;
+import org.jCharts.properties.LegendProperties;
+import org.jCharts.properties.PieChart2DProperties;
+import org.jCharts.test.TestDataGenerator;
+
+/**
+ * Demonstrates more complex form handling (including loops and dynamic
+ * addition/deletion of rows) as well as dynamic image generation using JCharts.
+ * 
+ * @author Howard Lewis Ship, Luis Neves
+ * @since 1.0.10
+ */
+
+public abstract class ChartPage extends BasePage implements IChartProvider, PageBeginRenderListener
+{
+
+    public abstract IValidationDelegate getDelegate();
+
+    /**
+     * Invokes {@link #getPlotValues()}, which ensures that (on the very first
+     * request cycle), the persistent values property is set <em>before</em>
+     * the page recorder is locked.
+     */
+
+    public void pageBeginRender(PageEvent event)
+    {
+        if (getPlotValues() == null)
+        {
+            List plotValues = new ArrayList();
+
+            plotValues.add(new PlotValue("Fred", 10));
+            plotValues.add(new PlotValue("Barney", 15));
+            plotValues.add(new PlotValue("Dino", 7));
+
+            setPlotValues(plotValues);
+        }
+    }
+
+    public abstract List getPlotValues();
+
+    public abstract void setPlotValues(List plotValues);
+
+    public abstract PlotValue getPlotValue();
+
+    public abstract List getRemoveValues();
+
+    public abstract void setRemoveValues(List removeValues);
+
+    /**
+     * Invoked during the render; always returns false.
+     */
+
+    public boolean isMarkedForDeletion()
+    {
+        return false;
+    }
+
+    /**
+     * Invoked by the deleted checkbox (for each plotValue). If true, the the
+     * current plotValue is added to the list of plotValues to remove (though
+     * the actual removing is done inside {@link #delete(IRequestCycle)}, after
+     * the loop.
+     */
+
+    public void setMarkedForDeletion(boolean value)
+    {
+        if (value)
+        {
+            List removeValues = getRemoveValues();
+
+            if (removeValues == null)
+            {
+                removeValues = new ArrayList();
+                setRemoveValues(removeValues);
+            }
+
+            removeValues.add(getPlotValue());
+
+            // Deleting things screws up the validation delegate.
+            // That's because the errors are associated with the form name
+            // (not the component id), and deleting elements causes
+            // all the names to shift.
+
+            getDelegate().clear();
+        }
+    }
+
+    /**
+     * Listener method for the add button, adds an additional (blank) plot
+     * value.
+     */
+
+    public void add()
+    {
+        if (getDelegate().getHasErrors()) return;
+
+        List plotValues = getPlotValues();
+
+        plotValues.add(new PlotValue());
+
+        setPlotValues(plotValues);
+    }
+
+    /**
+     * Listener method for the remove button, removes any checked plot values.
+     * 
+     * @see #setMarkedForDeletion(boolean)
+     */
+
+    public void delete()
+    {
+        if (getDelegate().getHasErrors()) return;
+
+        List removeValues = getRemoveValues();
+
+        if (removeValues != null)
+        {
+            List plotValues = getPlotValues();
+
+            plotValues.removeAll(removeValues);
+
+            setPlotValues(plotValues);
+        }
+    }
+
+    public IAsset getChartImageAsset()
+    {
+        return new ChartAsset(getRequestCycle(), this);
+    }
+
+    /**
+     * This method is invoked by the service (in a seperate request cycle from
+     * all the form handling stuff). The {@link #getChartImageAsset()}method
+     * provides an {@link IAsset}that is handled by the {@link ChartService},
+     * and the asset encodes the identity of this page.
+     */
+
+    public Chart getChart()
+    {
+        LegendProperties legendProperties = new LegendProperties();
+        legendProperties.setNumColumns(2);
+        legendProperties.setPlacement(LegendAreaProperties.RIGHT);
+        ChartProperties chartProperties = new ChartProperties();
+        chartProperties.setBackgroundPaint(Color.decode("#ffffcc"));
+
+        Chart result = new PieChart2D(getData(), legendProperties, chartProperties, 400, 350);
+
+        return result;
+    }
+
+    private PieChartDataSet getData()
+    {
+        List plotValues = getPlotValues();
+        int count = plotValues.size();
+        double[] data = new double[count];
+        String[] labels = new String[count];
+        PieChart2DProperties properties = new PieChart2DProperties();
+
+        for(int i = 0; i < count; i++)
+        {
+            PlotValue pv = (PlotValue)plotValues.get(i);
+
+            String name = pv.getName();
+
+            if (HiveMind.isBlank(name)) name = "<New>";
+
+            data[i] = new Double(pv.getValue()).doubleValue();
+            labels[i] = new String(name);
+        }
+
+        Paint[] paints = TestDataGenerator.getRandomPaints(count);
+
+        try
+        {
+            return new PieChartDataSet("Pie Chart", data, labels, paints, properties);
+        }
+        catch (ChartDataException e)
+        {
+            return null;
+        }
+    }
+
+}

Added: jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/chart/ChartService.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/chart/ChartService.java?rev=371786&view=auto
==============================================================================
--- jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/chart/ChartService.java (added)
+++ jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/chart/ChartService.java Mon Jan 23 19:04:45 2006
@@ -0,0 +1,137 @@
+// Copyright 2004, 2005 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ajaxworkbench.chart;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.hivemind.util.Defense;
+import org.apache.tapestry.IComponent;
+import org.apache.tapestry.IPage;
+import org.apache.tapestry.IRequestCycle;
+import org.apache.tapestry.engine.IEngineService;
+import org.apache.tapestry.engine.ILink;
+import org.apache.tapestry.error.RequestExceptionReporter;
+import org.apache.tapestry.services.LinkFactory;
+import org.apache.tapestry.services.ServiceConstants;
+import org.apache.tapestry.util.ContentType;
+import org.apache.tapestry.web.WebResponse;
+import org.jCharts.Chart;
+import org.jCharts.encoders.JPEGEncoder13;
+
+/**
+ * ServiceLink that works with a {@link Chart}to dynamically render a chart as a JPEG. This is a
+ * very limited implementation; a full version would include features such as setting the size of
+ * the image, and more flexibility in defining where the {@link Chart}instance is obtained from.
+ * 
+ * @author Howard Lewis Ship
+ * @since 1.0.10
+ */
+
+public class ChartService implements IEngineService
+{
+    public static final String SERVICE_NAME = "chart";
+
+    /** @since 4.0 */
+    private RequestExceptionReporter _exceptionReporter;
+
+    /** @since 4.0 */
+    private LinkFactory _linkFactory;
+
+    /** @since 4.0 */
+    private WebResponse _response;
+
+    public ILink getLink(boolean post, Object parameter)
+    {
+        Defense.isAssignable(parameter, IComponent.class, "parameter");
+
+        IComponent component = (IComponent) parameter;
+
+        Map parameters = new HashMap();
+
+        parameters.put(ServiceConstants.SERVICE, getName());
+        parameters.put(ServiceConstants.PAGE, component.getPage().getPageName());
+        parameters.put(ServiceConstants.COMPONENT, component.getIdPath());
+
+        return _linkFactory.constructLink(this, false, parameters, true);
+    }
+
+    public void service(IRequestCycle cycle) throws IOException
+    {
+        String pageName = cycle.getParameter(ServiceConstants.PAGE);
+        String componentId = cycle.getParameter(ServiceConstants.COMPONENT);
+
+        IPage page = cycle.getPage(pageName);
+        IComponent component = page.getNestedComponent(componentId);
+
+        try
+        {
+            IChartProvider provider = (IChartProvider) component;
+
+            Chart chart = provider.getChart();
+
+            OutputStream output = _response.getOutputStream(new ContentType("image/jpeg"));
+
+            // I've seen a few bits of wierdness (including a JVM crash) inside this code.
+            // Hopefully, its a multi-threading problem that can be resolved
+            // by synchronizing.
+
+            synchronized (this)
+            {
+                JPEGEncoder13.encode(chart, 1.0f, output);
+            }
+        }
+        catch (ClassCastException ex)
+        {
+            _exceptionReporter.reportRequestException("Component " + component.getExtendedId()
+                    + " does not implement IChartProvider.", ex);
+
+            return;
+        }
+        catch (Throwable ex)
+        {
+            _exceptionReporter.reportRequestException("Error creating JPEG stream.", ex);
+
+            return;
+        }
+
+        return;
+    }
+
+    public String getName()
+    {
+        return SERVICE_NAME;
+    }
+
+    /** @since 4.0 */
+    public void setExceptionReporter(RequestExceptionReporter exceptionReporter)
+    {
+        _exceptionReporter = exceptionReporter;
+    }
+
+    /** @since 4.0 */
+    public void setLinkFactory(LinkFactory linkFactory)
+    {
+        _linkFactory = linkFactory;
+    }
+
+    /** @since 4.0 */
+    public void setResponse(WebResponse response)
+    {
+        _response = response;
+    }
+}
\ No newline at end of file

Added: jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/chart/IChartProvider.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/chart/IChartProvider.java?rev=371786&view=auto
==============================================================================
--- jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/chart/IChartProvider.java (added)
+++ jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/chart/IChartProvider.java Mon Jan 23 19:04:45 2006
@@ -0,0 +1,29 @@
+// Copyright 2004, 2005 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ajaxworkbench.chart;
+
+import org.jCharts.Chart;
+
+/**
+ * An object which can provide a {@link Chart}(to the {@link ChartService}).
+ * 
+ * @author Howard Lewis Ship
+ * @since 1.0.10
+ */
+
+public interface IChartProvider
+{
+    public Chart getChart();
+}
\ No newline at end of file

Added: jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/chart/PlotValue.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/chart/PlotValue.java?rev=371786&view=auto
==============================================================================
--- jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/chart/PlotValue.java (added)
+++ jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/chart/PlotValue.java Mon Jan 23 19:04:45 2006
@@ -0,0 +1,77 @@
+// Copyright 2004, 2005, 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.tapestry.ajaxworkbench.chart;
+
+import java.io.Serializable;
+
+/**
+ * An single point of data in the plot.
+ * 
+ * @author Howard Lewis Ship
+ * @since 1.0.10
+ */
+
+public class PlotValue implements Serializable
+{
+
+    private static final long serialVersionUID = 4847193821463693432L;
+
+    private String name;
+
+    private int value;
+
+    public PlotValue()
+    {
+    }
+
+    public PlotValue(String name, int value)
+    {
+        this.name = name;
+        this.value = value;
+    }
+
+    public String getName()
+    {
+        return name;
+    }
+
+    public void setName(String name)
+    {
+        this.name = name;
+    }
+
+    public int getValue()
+    {
+        return value;
+    }
+
+    public void setValue(int value)
+    {
+        this.value = value;
+    }
+
+    public String toString()
+    {
+        StringBuffer buffer = new StringBuffer("PlotValue@");
+        buffer.append(Integer.toHexString(hashCode()));
+        buffer.append('[');
+        buffer.append(name);
+        buffer.append(' ');
+        buffer.append(value);
+        buffer.append(']');
+
+        return buffer.toString();
+    }
+}

Added: jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/components/.cvsignore
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/components/.cvsignore?rev=371786&view=auto
==============================================================================
--- jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/components/.cvsignore (added)
+++ jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/components/.cvsignore Mon Jan 23 19:04:45 2006
@@ -0,0 +1 @@
+*.jbf

Added: jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/components/Border.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/components/Border.java?rev=371786&view=auto
==============================================================================
--- jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/components/Border.java (added)
+++ jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/components/Border.java Mon Jan 23 19:04:45 2006
@@ -0,0 +1,137 @@
+// Copyright 2004, 2005 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ajaxworkbench.components;
+
+import org.apache.tapestry.BaseComponent;
+import org.apache.tapestry.IAsset;
+import org.apache.tapestry.IRequestCycle;
+import org.apache.tapestry.TapestryUtils;
+import org.apache.tapestry.ajaxworkbench.Visit;
+import org.apache.tapestry.annotations.Asset;
+import org.apache.tapestry.annotations.InjectAsset;
+import org.apache.tapestry.annotations.InjectState;
+import org.apache.tapestry.annotations.Message;
+import org.apache.tapestry.event.PageBeginRenderListener;
+import org.apache.tapestry.event.PageEvent;
+
+/**
+ * Common navigational border for the Workbench tutorial.
+ * 
+ * @author Howard Lewis Ship
+ * @since 1.0.7
+ */
+
+public abstract class Border extends BaseComponent implements PageBeginRenderListener
+{
+
+    /**
+     * Array of page names, read from the Strings file; this is the same regardless of localization,
+     * so it is static (shared by all).
+     */
+
+    private static String[] _tabOrder;
+
+    @InjectState("visit")
+    public abstract Visit getVisit();
+
+    @Message
+    public abstract String getTabOrder();
+
+    public void pageBeginRender(PageEvent event)
+    {
+        Visit visit = getVisit();
+
+        setActivePageName(visit.getActiveTabName());
+
+        if (_tabOrder == null)
+            _tabOrder = TapestryUtils.split(getTabOrder(), ' ');
+    }
+
+    /**
+     * Returns the logical names of the pages accessible via the navigation bar, in appopriate
+     * order.
+     */
+
+    public String[] getPageTabNames()
+    {
+        return _tabOrder;
+    }
+
+    public abstract void setPageName(String value);
+
+    public abstract String getPageName();
+
+    public abstract void setActivePageName(String activePageName);
+
+    public abstract String getActivePageName();
+
+    public boolean isActivePage()
+    {
+        return getPageName().equals(getActivePageName());
+    }
+
+    public String getPageTitle()
+    {
+        // Need to check for synchronization issues, but I think
+        // ResourceBundle is safe.
+
+        return getMessages().getMessage(getPageName());
+    }
+
+    // Arbitrary mix of @Asset and @InjectAsset just to
+    // test the annotations.
+
+    @Asset("images/tab-active-left.gif")
+    public abstract IAsset getActiveLeft();
+
+    @InjectAsset("inactiveLeft")
+    public abstract IAsset getInactiveLeft();
+
+    @Asset("images/tab-active-mid.gif")
+    public abstract IAsset getActiveMid();
+
+    @InjectAsset("inactiveMid")
+    public abstract IAsset getInactiveMid();
+
+    @Asset("images/tab-active-right.gif")
+    public abstract IAsset getActiveRight();
+
+    @InjectAsset("inactiveRight")
+    public abstract IAsset getInactiveRight();
+
+    public IAsset getLeftTabAsset()
+    {
+        return isActivePage() ? getActiveLeft() : getInactiveLeft();
+    }
+
+    public IAsset getMidTabAsset()
+    {
+        return isActivePage() ? getActiveMid() : getInactiveMid();
+    }
+
+    public IAsset getRightTabAsset()
+    {
+        return isActivePage() ? getActiveRight() : getInactiveRight();
+    }
+
+    public void selectPage(IRequestCycle cycle, String newPageName)
+    {
+        Visit visit = getVisit();
+
+        visit.setActiveTabName(newPageName);
+
+        cycle.activate(newPageName);
+    }
+}
\ No newline at end of file

Added: jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/components/ShowError.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/components/ShowError.java?rev=371786&view=auto
==============================================================================
--- jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/components/ShowError.java (added)
+++ jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/components/ShowError.java Mon Jan 23 19:04:45 2006
@@ -0,0 +1,74 @@
+// Copyright 2005 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ajaxworkbench.components;
+
+import java.util.List;
+
+import org.apache.tapestry.AbstractComponent;
+import org.apache.tapestry.IMarkupWriter;
+import org.apache.tapestry.IRender;
+import org.apache.tapestry.IRequestCycle;
+import org.apache.tapestry.annotations.ComponentClass;
+import org.apache.tapestry.annotations.Parameter;
+import org.apache.tapestry.valid.IValidationDelegate;
+
+/**
+ * This would normally be done entirely <em>without</em> using code. Trying to demonstrate that
+ * you can create components without a .jwc file by matching the component type against a class name
+ * (in the proper package, as defined in the application specification).
+ * 
+ * @author Howard Lewis Ship
+ * @since 4.0
+ */
+@ComponentClass(allowBody = false, allowInformalParameters = false)
+public abstract class ShowError extends AbstractComponent
+{
+    @Parameter(required = true)
+    public abstract IValidationDelegate getDelegate();
+
+    @Override
+    protected void renderComponent(IMarkupWriter writer, IRequestCycle cycle)
+    {
+        if (cycle.isRewinding())
+            return;
+
+        IValidationDelegate delegate = getDelegate();
+
+        if (!delegate.getHasErrors())
+            return;
+
+        writer.begin("table");
+        writer.attribute("class", "inputerror");
+
+        writer.begin("tr");
+        writer.attribute("valign", "top");
+
+        writer.begin("td");
+        writer.beginEmpty("img");
+        writer.attribute("src", "images/Warning.gif");
+        writer.attribute("width", 42);
+        writer.attribute("height", 41);
+        writer.end();
+
+        writer.begin("td");
+        writer.attribute("class", "message");
+
+        List<IRender> errorRenders = delegate.getErrorRenderers();
+
+        errorRenders.get(0).render(writer, cycle);
+
+        writer.end("table");
+    }
+}

Added: jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/fields/Fields.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/fields/Fields.java?rev=371786&view=auto
==============================================================================
--- jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/fields/Fields.java (added)
+++ jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/fields/Fields.java Mon Jan 23 19:04:45 2006
@@ -0,0 +1,69 @@
+// Copyright 2004, 2005 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ajaxworkbench.fields;
+
+import java.math.BigDecimal;
+
+import org.apache.tapestry.IPage;
+import org.apache.tapestry.annotations.InjectPage;
+import org.apache.tapestry.html.BasePage;
+import org.apache.tapestry.valid.IValidationDelegate;
+
+/**
+ * @author Howard Lewis Ship
+ * @since 1.0.7
+ */
+
+public abstract class Fields extends BasePage
+{
+    public static final int INT_MIN = 5;
+
+    public static final int INT_MAX = 20;
+
+    public static final double DOUBLE_MIN = 3.14;
+
+    public static final double DOUBLE_MAX = 27.5;
+
+    public static final BigDecimal DECIMAL_MIN = new BigDecimal("2");
+
+    public static final BigDecimal DECIMAL_MAX = new BigDecimal(
+            "100.123456234563456734563456356734567456784567456784567845675678456785678");
+
+    public static final long LONG_MIN = 6;
+
+    public static final long LONG_MAX = 21;
+
+    public static final int STRING_MIN_LENGTH = 3;
+
+    @InjectPage("FieldsResults")
+    public abstract FieldsResults getResultsPage();
+
+    public IPage doSubmit()
+    {
+        return getResultsPage();
+    }
+
+    public void doByLink()
+    {
+        getResultsPage().setByLink(true);
+    }
+
+    /**
+     * Injected.
+     * 
+     * @since 4.0
+     */
+    public abstract IValidationDelegate getDelegate();
+}
\ No newline at end of file

Added: jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/fields/FieldsResults.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/fields/FieldsResults.java?rev=371786&view=auto
==============================================================================
--- jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/fields/FieldsResults.java (added)
+++ jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/fields/FieldsResults.java Mon Jan 23 19:04:45 2006
@@ -0,0 +1,30 @@
+// Copyright 2005 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ajaxworkbench.fields;
+
+import org.apache.tapestry.html.BasePage;
+
+/**
+ * @author Howard Lewis Ship
+ * @since 4.0
+ */
+public abstract class FieldsResults extends BasePage
+{
+    /**
+     * Flag indicating whether the form was submitted via a link.
+     */
+
+    public abstract void setByLink(boolean byLink);
+}

Added: jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/localization/LocaleModel.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/localization/LocaleModel.java?rev=371786&view=auto
==============================================================================
--- jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/localization/LocaleModel.java (added)
+++ jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/localization/LocaleModel.java Mon Jan 23 19:04:45 2006
@@ -0,0 +1,78 @@
+// Copyright 2004, 2005 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ajaxworkbench.localization;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+
+import org.apache.tapestry.form.IPropertySelectionModel;
+
+/**
+ * @author Howard Lewis Ship
+ */
+
+public class LocaleModel implements IPropertySelectionModel
+{
+    private Locale _locale;
+
+    private List _locales = new ArrayList();
+
+    public LocaleModel(Locale locale)
+    {
+        _locale = locale;
+    }
+
+    public void add(Locale locale)
+    {
+        _locales.add(locale);
+    }
+
+    private Locale get(int index)
+    {
+        return (Locale) _locales.get(index);
+    }
+
+    public String getLabel(int index)
+    {
+        return get(index).getDisplayName(_locale);
+    }
+
+    public int getOptionCount()
+    {
+        return _locales.size();
+    }
+
+    public Object getOption(int index)
+    {
+        return _locales.get(index);
+    }
+
+    /**
+     * Returns the String version of the integer index.
+     */
+
+    public String getValue(int index)
+    {
+        return Integer.toString(index);
+    }
+
+    public Object translateValue(String value)
+    {
+        int index = Integer.parseInt(value);
+
+        return _locales.get(index);
+    }
+}
\ No newline at end of file

Added: jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/localization/Localization.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/localization/Localization.java?rev=371786&view=auto
==============================================================================
--- jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/localization/Localization.java (added)
+++ jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/localization/Localization.java Mon Jan 23 19:04:45 2006
@@ -0,0 +1,57 @@
+// Copyright 2004, 2005 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ajaxworkbench.localization;
+
+import java.util.Locale;
+
+import org.apache.tapestry.IRequestCycle;
+import org.apache.tapestry.form.IPropertySelectionModel;
+import org.apache.tapestry.html.BasePage;
+
+/**
+ * @author Howard Lewis Ship
+ * @since 1.0.7
+ */
+
+public abstract class Localization extends BasePage
+{
+    private IPropertySelectionModel localeModel;
+
+    public void formSubmit(IRequestCycle cycle)
+    {
+        cycle.activate("localization/Change");
+    }
+
+    public IPropertySelectionModel getLocaleModel()
+    {
+        if (localeModel == null)
+            localeModel = buildLocaleModel();
+
+        return localeModel;
+    }
+
+    private IPropertySelectionModel buildLocaleModel()
+    {
+        LocaleModel model = new LocaleModel(getLocale());
+
+        model.add(Locale.ENGLISH);
+        model.add(Locale.FRENCH);
+        model.add(Locale.GERMAN);
+        model.add(Locale.ITALIAN);
+
+        return model;
+    }
+
+}
\ No newline at end of file

Added: jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/localization/LocalizationChange.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/localization/LocalizationChange.java?rev=371786&view=auto
==============================================================================
--- jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/localization/LocalizationChange.java (added)
+++ jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/localization/LocalizationChange.java Mon Jan 23 19:04:45 2006
@@ -0,0 +1,40 @@
+// Copyright 2004, 2005 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ajaxworkbench.localization;
+
+import java.util.Locale;
+
+import org.apache.tapestry.html.BasePage;
+
+/**
+ * @author Howard Lewis Ship
+ */
+
+public abstract class LocalizationChange extends BasePage
+{
+    private String localeName;
+
+    public String getLocaleName()
+    {
+        if (localeName == null)
+        {
+            Locale locale = getLocale();
+
+            localeName = locale.getDisplayName(locale);
+        }
+
+        return localeName;
+    }
+}
\ No newline at end of file

Added: jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/palette/Palette.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/palette/Palette.java?rev=371786&view=auto
==============================================================================
--- jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/palette/Palette.java (added)
+++ jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/palette/Palette.java Mon Jan 23 19:04:45 2006
@@ -0,0 +1,81 @@
+// Copyright 2004, 2005 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ajaxworkbench.palette;
+
+import java.util.List;
+
+import org.apache.tapestry.IPage;
+import org.apache.tapestry.annotations.InjectPage;
+import org.apache.tapestry.annotations.Persist;
+import org.apache.tapestry.contrib.palette.SortMode;
+import org.apache.tapestry.form.IPropertySelectionModel;
+import org.apache.tapestry.form.StringPropertySelectionModel;
+import org.apache.tapestry.html.BasePage;
+import org.apache.tapestry.valid.IValidationDelegate;
+
+/**
+ * @author Howard Lewis Ship
+ */
+
+public abstract class Palette extends BasePage
+{
+    public abstract List getSelectedColors();
+
+    @Persist("client:app")
+    public abstract String getSort();
+
+    public abstract void setSort(String sort);
+
+    public abstract IValidationDelegate getDelegate();
+
+    @InjectPage("PaletteResults")
+    public abstract PaletteResults getResultsPage();
+
+    protected void finishLoad()
+    {
+        setSort(SortMode.USER);
+    }
+
+    public void doRefresh()
+    {
+        getDelegate().clearErrors();
+    }
+
+    public IPage doAdvance()
+    {
+        // Since Palette and palette.Results come from
+        // a library now, we need to make sure
+        // the namespace id is part of the name.
+
+        PaletteResults results = getResultsPage();
+
+        results.setSelectedColors(getSelectedColors());
+
+        return results;
+    }
+
+    private IPropertySelectionModel colorModel;
+
+    private String[] colors =
+    { "Red", "Orange", "Yellow", "Green", "Blue", "Indigo", "Violet" };
+
+    public IPropertySelectionModel getColorModel()
+    {
+        if (colorModel == null)
+            colorModel = new StringPropertySelectionModel(colors);
+
+        return colorModel;
+    }
+}
\ No newline at end of file

Added: jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/palette/PaletteResults.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/palette/PaletteResults.java?rev=371786&view=auto
==============================================================================
--- jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/palette/PaletteResults.java (added)
+++ jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/palette/PaletteResults.java Mon Jan 23 19:04:45 2006
@@ -0,0 +1,30 @@
+// Copyright 2004, 2005 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ajaxworkbench.palette;
+
+import java.util.List;
+
+import org.apache.tapestry.html.BasePage;
+
+/**
+ * @author Howard Lewis Ship
+ * @since 1.0.7
+ */
+
+public abstract class PaletteResults extends BasePage
+{
+    public abstract void setSelectedColors(List value);
+
+}
\ No newline at end of file

Added: jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/palette/SortModeStrings.properties
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/palette/SortModeStrings.properties?rev=371786&view=auto
==============================================================================
--- jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/palette/SortModeStrings.properties (added)
+++ jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/palette/SortModeStrings.properties Mon Jan 23 19:04:45 2006
@@ -0,0 +1,18 @@
+# Copyright 2004, 2005 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+NONE=None
+LABEL=Label
+VALUE=Value
+USER=Manual
\ No newline at end of file

Added: jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/table/ILocaleSelectionListener.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/table/ILocaleSelectionListener.java?rev=371786&view=auto
==============================================================================
--- jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/table/ILocaleSelectionListener.java (added)
+++ jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/table/ILocaleSelectionListener.java Mon Jan 23 19:04:45 2006
@@ -0,0 +1,26 @@
+// Copyright 2004, 2005 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ajaxworkbench.table;
+
+import java.util.Locale;
+
+/**
+ * @author mindbridge
+ *
+ */
+public interface ILocaleSelectionListener
+{
+    void localesSelected(Locale[] arrLocales);
+}

Added: jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/table/LocaleList.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/table/LocaleList.java?rev=371786&view=auto
==============================================================================
--- jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/table/LocaleList.java (added)
+++ jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/table/LocaleList.java Mon Jan 23 19:04:45 2006
@@ -0,0 +1,115 @@
+// Copyright 2004, 2005 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ajaxworkbench.table;
+
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import org.apache.tapestry.BaseComponent;
+import org.apache.tapestry.IRequestCycle;
+import org.apache.tapestry.annotations.Parameter;
+import org.apache.tapestry.contrib.table.model.IPrimaryKeyConvertor;
+
+/**
+ * @author mindbridge
+ */
+public abstract class LocaleList extends BaseComponent
+{
+
+    @Parameter(required = true)
+    public abstract ILocaleSelectionListener getLocaleSelectionListener();
+
+    // immutable values
+    private IPrimaryKeyConvertor m_objLocaleConvertor;
+
+    public LocaleList()
+    {
+        // define an IPrimaryKeyConvertor that represents
+        // a Locale object as a String and converts it back
+        m_objLocaleConvertor = new IPrimaryKeyConvertor()
+        {
+            public Object getPrimaryKey(Object objValue)
+            {
+                Locale objLocale = (Locale) objValue;
+                return objLocale.toString();
+            }
+
+            public Object getValue(Object objPrimaryKey)
+            {
+                StringTokenizer objTokenizer = new StringTokenizer((String) objPrimaryKey, "_");
+
+                String strLanguage = "";
+                if (objTokenizer.hasMoreTokens())
+                    strLanguage = objTokenizer.nextToken();
+
+                String strCountry = "";
+                if (objTokenizer.hasMoreTokens())
+                    strCountry = objTokenizer.nextToken();
+
+                String strVariant = "";
+                if (objTokenizer.hasMoreTokens())
+                    strVariant = objTokenizer.nextToken();
+
+                return new Locale(strLanguage, strCountry, strVariant);
+            }
+        };
+    }
+
+    public IPrimaryKeyConvertor getLocaleConvertor()
+    {
+        return m_objLocaleConvertor;
+    }
+
+    public boolean getCheckboxSelected()
+    {
+        return getSelectedLocales().contains(getCurrentLocale());
+    }
+
+    public void setCheckboxSelected(boolean bSelected)
+    {
+        Locale objLocale = getCurrentLocale();
+        Set setSelectedLocales = getSelectedLocales();
+
+        if (bSelected)
+            setSelectedLocales.add(objLocale);
+        else
+            setSelectedLocales.remove(objLocale);
+
+        // persist value
+        setSelectedLocales(setSelectedLocales);
+    }
+
+    public void selectLocales(IRequestCycle objCycle)
+    {
+        Set setSelectedLocales = getSelectedLocales();
+        Locale[] arrLocales = new Locale[setSelectedLocales.size()];
+        setSelectedLocales.toArray(arrLocales);
+
+        ILocaleSelectionListener objListener = getLocaleSelectionListener();
+
+        objListener.localesSelected(arrLocales);
+
+        // clear selection
+        setSelectedLocales(new HashSet());
+    }
+
+    public abstract Locale getCurrentLocale();
+
+    public abstract Set getSelectedLocales();
+
+    public abstract void setSelectedLocales(Set set);
+}
\ No newline at end of file

Added: jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/table/LocaleSelection.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/table/LocaleSelection.java?rev=371786&view=auto
==============================================================================
--- jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/table/LocaleSelection.java (added)
+++ jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/table/LocaleSelection.java Mon Jan 23 19:04:45 2006
@@ -0,0 +1,162 @@
+// Copyright 2004, 2005 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ajaxworkbench.table;
+
+import java.text.DateFormat;
+import java.text.DecimalFormatSymbols;
+import java.util.Date;
+import java.util.Locale;
+import java.util.Set;
+
+import org.apache.tapestry.BaseComponent;
+import org.apache.tapestry.IRequestCycle;
+import org.apache.tapestry.contrib.table.model.ITableColumn;
+import org.apache.tapestry.contrib.table.model.simple.ITableColumnEvaluator;
+import org.apache.tapestry.contrib.table.model.simple.SimpleTableColumn;
+
+/**
+ * @author mindbridge
+ */
+public abstract class LocaleSelection extends BaseComponent implements ILocaleSelectionListener
+{
+    // properties
+    public abstract Locale getCurrentLocale();
+
+    public abstract Set getLocaleSet();
+
+    public abstract void setLocaleSet(Set objLocaleSet);
+
+    /**
+     * @see org.apache.tapestry.ajaxworkbench.table.ILocaleSelectionListener#localesSelected(Locale[])
+     */
+    public void localesSelected(Locale[] arrLocales)
+    {
+        Set objLocaleSet = getLocaleSet();
+        addAll(objLocaleSet, arrLocales);
+        // ensure that the framework knows about the change and the set is persisted
+        setLocaleSet(objLocaleSet);
+    }
+
+    private void addAll(Set objLocaleSet, Locale[] arrLocales)
+    {
+        for (int i = 0; i < arrLocales.length; i++)
+            objLocaleSet.add(arrLocales[i]);
+    }
+
+    public ITableColumn getCurrencyColumn()
+    {
+        // The column value is extracted in a custom evaluator class
+        return new SimpleTableColumn("Currency", new CurrencyEvaluator(), true);
+    }
+
+    public ITableColumn getDateFormatColumn()
+    {
+        // The entire column is defined using a custom column class
+        return new DateFormatColumn(new Date());
+    }
+
+    /**
+     * Returns the verbosity of the current locale. This is used by the Block rendering the
+     * 'Verbosity' column
+     * 
+     * @return int the current locale verbosity
+     */
+    public int getCurrentLocaleVerbosity()
+    {
+        int nVerbosity = VerbosityRating.calculateVerbosity(getCurrentLocale());
+        return nVerbosity;
+    }
+
+    /**
+     * Generates the context that will be passed to the deleteLocale() listener if a "remove" link
+     * is selected.
+     * <p>
+     * This is used by the Block rendering the 'Remove' column.
+     * 
+     * @return String[] the context for the deleteLocale() listener
+     */
+    public String[] getDeleteLocaleContext()
+    {
+        Locale objLocale = getCurrentLocale();
+        return new String[]
+        { objLocale.getLanguage(), objLocale.getCountry(), objLocale.getVariant() };
+    }
+
+    /**
+     * A listener invoked when a "remove" link is selected. It removes from the data model the
+     * locale corresponding to the link.
+     * <p>
+     * 
+     * @param objCycle
+     *            the request cycle
+     */
+    public void deleteLocale(IRequestCycle objCycle)
+    {
+        Object[] arrParams = objCycle.getListenerParameters();
+        Locale objLocale = new Locale(arrParams[0].toString(), arrParams[1].toString(),
+                arrParams[2].toString());
+        getLocaleSet().remove(objLocale);
+    }
+
+    /**
+     * A class defining the logic for getting the currency symbol from a locale
+     */
+    private static class CurrencyEvaluator implements ITableColumnEvaluator
+    {
+        private static final long serialVersionUID = 1L;
+
+        /**
+         * @see org.apache.tapestry.contrib.table.model.simple.ITableColumnEvaluator#getColumnValue(ITableColumn,
+         *      Object)
+         */
+        public Object getColumnValue(ITableColumn objColumn, Object objRow)
+        {
+            Locale objLocale = (Locale) objRow;
+            String strCountry = objLocale.getCountry();
+            if (strCountry == null || strCountry.equals(""))
+                return "";
+
+            DecimalFormatSymbols objSymbols = new DecimalFormatSymbols(objLocale);
+            return objSymbols.getCurrencySymbol();
+        }
+    }
+
+    /**
+     * A class defining a column for displaying the date format
+     */
+    private static class DateFormatColumn extends SimpleTableColumn
+    {
+        private static final long serialVersionUID = 1L;
+
+        private Date m_objDate;
+
+        public DateFormatColumn(Date objDate)
+        {
+            super("Date Format", true);
+            m_objDate = objDate;
+        }
+
+        public Object getColumnValue(Object objRow)
+        {
+            Locale objLocale = (Locale) objRow;
+            DateFormat objFormat = DateFormat.getDateTimeInstance(
+                    DateFormat.LONG,
+                    DateFormat.LONG,
+                    objLocale);
+            return objFormat.format(m_objDate);
+        }
+    }
+
+}
\ No newline at end of file

Added: jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/table/VerbosityRating.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/table/VerbosityRating.java?rev=371786&view=auto
==============================================================================
--- jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/table/VerbosityRating.java (added)
+++ jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/table/VerbosityRating.java Mon Jan 23 19:04:45 2006
@@ -0,0 +1,106 @@
+// Copyright 2004, 2005, 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.tapestry.ajaxworkbench.table;
+
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.Locale;
+
+/**
+ * @author mindbridge
+ */
+public final class VerbosityRating
+{
+
+    /** @since 4.1 */
+    private VerbosityRating()
+    {
+    }
+
+    /**
+     * Method calculateVerbosity. Please note that this method is relatively
+     * slow It should not be used often, unless for fun :)
+     * 
+     * @param objLocale
+     * @return int
+     */
+    public static int calculateVerbosity(Locale objLocale)
+    {
+        int nWeekDayVerbosity = calculateWeekDayVerbosity(objLocale);
+        int nMonthVerbosity = calculateMonthVerbosity(objLocale);
+        return nWeekDayVerbosity + nMonthVerbosity;
+    }
+
+    public static int calculateWeekDayVerbosity(Locale objLocale)
+    {
+        SimpleDateFormat objWeekDay = new SimpleDateFormat("EEEE", objLocale);
+
+        GregorianCalendar objCalendar = new GregorianCalendar();
+        objCalendar.set(Calendar.YEAR, 2000);
+        objCalendar.set(Calendar.MONTH, 0);
+        objCalendar.set(Calendar.DATE, 1);
+
+        int nCount = 0;
+        for(int i = 0; i < 7; i++)
+        {
+            String strWeekDay = objWeekDay.format(objCalendar.getTime());
+            nCount += strWeekDay.length();
+            objCalendar.add(Calendar.DATE, 1);
+        }
+
+        return nCount;
+    }
+
+    public static int calculateMonthVerbosity(Locale objLocale)
+    {
+        SimpleDateFormat objMonth = new SimpleDateFormat("MMMM", objLocale);
+
+        GregorianCalendar objCalendar = new GregorianCalendar();
+        objCalendar.set(Calendar.YEAR, 2000);
+        objCalendar.set(Calendar.MONTH, 0);
+        objCalendar.set(Calendar.DATE, 1);
+
+        int nCount = 0;
+        for(int i = 0; i < 12; i++)
+        {
+            String strMonth = objMonth.format(objCalendar.getTime());
+            nCount += strMonth.length();
+            objCalendar.add(Calendar.MONTH, 1);
+        }
+
+        return nCount;
+    }
+
+    // public static void main(String[] arrArgs)
+    // {
+    // int nMax = 0;
+    // int nMin = 1000;
+    //
+    // System.out.println("Starting");
+    //
+    // Locale[] arrLocales = Locale.getAvailableLocales();
+    // for(int i = 0; i < arrLocales.length; i++) {
+    // Locale objLocale = arrLocales[i];
+    // int nRating = calculateVerbosity(objLocale);
+    // if (nRating > nMax) nMax = nRating;
+    // if (nRating < nMin) nMin = nRating;
+    // }
+    //
+    // System.out.println("Min: " + nMin);
+    // System.out.println("Max: " + nMax);
+    // }
+
+}

Added: jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/tree/examples/DirectoryTableView.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/tree/examples/DirectoryTableView.java?rev=371786&view=auto
==============================================================================
--- jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/tree/examples/DirectoryTableView.java (added)
+++ jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/tree/examples/DirectoryTableView.java Mon Jan 23 19:04:45 2006
@@ -0,0 +1,143 @@
+// Copyright 2004, 2005, 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.tapestry.ajaxworkbench.tree.examples;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.apache.tapestry.BaseComponent;
+import org.apache.tapestry.IBinding;
+import org.apache.tapestry.ajaxworkbench.tree.examples.fsmodel.SFObject;
+import org.apache.tapestry.contrib.table.components.Table;
+import org.apache.tapestry.contrib.table.model.ITableColumn;
+import org.apache.tapestry.contrib.table.model.ITableModel;
+import org.apache.tapestry.contrib.table.model.simple.SimpleTableColumn;
+import org.apache.tapestry.contrib.table.model.simple.SimpleTableModel;
+import org.apache.tapestry.event.PageDetachListener;
+import org.apache.tapestry.event.PageEvent;
+
+/**
+ * @author ceco
+ */
+public abstract class DirectoryTableView extends BaseComponent implements PageDetachListener
+{
+
+    private ITableModel m_objTableModel = null;
+
+    private ITableColumn[] m_arrColumns = null;
+
+    private ISelectedFolderSource m_objSelectedFolderSource = null;
+
+    /**
+     * 
+     */
+    public DirectoryTableView()
+    {
+        super();
+        initialize();
+    }
+
+    private void initialize()
+    {
+        m_objTableModel = null;
+        m_objSelectedFolderSource = null;
+    }
+
+    /**
+     * @see org.apache.tapestry.AbstractComponent#finishLoad()
+     */
+    protected void finishLoad()
+    {
+        super.finishLoad();
+        getPage().addPageDetachListener(this);
+    }
+
+    /**
+     * @see org.apache.tapestry.event.PageDetachListener#pageDetached(org.apache.tapestry.event.PageEvent)
+     */
+    public void pageDetached(PageEvent arg0)
+    {
+        initialize();
+    }
+
+    public ITableModel getTableModel()
+    {
+        if (m_objTableModel == null)
+        {
+            ISelectedFolderSource objSelectedFolderSource = getSelectedFolderSource();
+            Collection colChildrens = objSelectedFolderSource.getSelectedFolderChildren();
+
+            m_objTableModel = new SimpleTableModel(colChildrens.toArray(), getColumns());
+        }
+        return m_objTableModel;
+    }
+
+    public ITableColumn[] getColumns()
+    {
+        if (m_arrColumns == null)
+        {
+            ArrayList arrColumnsList = new ArrayList();
+            arrColumnsList.add(new SimpleTableColumn("Name", true)
+            {
+
+                private static final long serialVersionUID = -5394217017984056107L;
+
+                public Object getColumnValue(Object objValue)
+                {
+                    SFObject objSFObject = (SFObject)objValue;
+                    return objSFObject.getName();
+                }
+            });
+
+            arrColumnsList.add(new SimpleTableColumn("Date", true)
+            {
+
+                private static final long serialVersionUID = -3258043732869364037L;
+
+                public Object getColumnValue(Object objValue)
+                {
+                    SFObject objSFObject = (SFObject)objValue;
+                    return objSFObject.getDate();
+                }
+            });
+
+            m_arrColumns = new SimpleTableColumn[arrColumnsList.size()];
+            arrColumnsList.toArray(m_arrColumns);
+        }
+        return m_arrColumns;
+    }
+
+    public ISelectedFolderSource getSelectedFolderSource()
+    {
+        if (m_objSelectedFolderSource == null)
+        {
+            IBinding objBinding = getBinding("selectedFolderSource");
+            m_objSelectedFolderSource = (ISelectedFolderSource)objBinding.getObject();
+        }
+        return m_objSelectedFolderSource;
+    }
+
+    public void resetState()
+    {
+        initialize();
+        Table objTable = (Table)getComponent("table");
+        objTable.reset();
+    }
+
+    public String getSelectedNodeName()
+    {
+        return getSelectedFolderSource().getSelectedNodeName();
+    }
+}

Added: jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/tree/examples/FileSystemTree.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/tree/examples/FileSystemTree.java?rev=371786&view=auto
==============================================================================
--- jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/tree/examples/FileSystemTree.java (added)
+++ jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/tree/examples/FileSystemTree.java Mon Jan 23 19:04:45 2006
@@ -0,0 +1,208 @@
+// Copyright 2004, 2005, 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.tapestry.ajaxworkbench.tree.examples;
+
+import java.io.File;
+import java.util.Collection;
+import java.util.Date;
+
+import org.apache.tapestry.ajaxworkbench.tree.examples.fsmodel.FileSystem;
+import org.apache.tapestry.ajaxworkbench.tree.examples.fsmodel.FileSystemDataModel;
+import org.apache.tapestry.ajaxworkbench.tree.examples.fsmodel.FileSystemStateManager;
+import org.apache.tapestry.ajaxworkbench.tree.examples.fsmodel.FolderObject;
+import org.apache.tapestry.ajaxworkbench.tree.examples.fsmodel.NodeRenderFactory;
+import org.apache.tapestry.annotations.InjectObject;
+import org.apache.tapestry.contrib.tree.components.INodeRenderFactory;
+import org.apache.tapestry.contrib.tree.components.TreeView;
+import org.apache.tapestry.contrib.tree.model.ITreeDataModel;
+import org.apache.tapestry.contrib.tree.model.ITreeModel;
+import org.apache.tapestry.contrib.tree.model.ITreeNode;
+import org.apache.tapestry.contrib.tree.model.ITreeSessionStateManager;
+import org.apache.tapestry.contrib.tree.model.ITreeStateListener;
+import org.apache.tapestry.contrib.tree.model.ITreeStateModel;
+import org.apache.tapestry.contrib.tree.model.TreeStateEvent;
+import org.apache.tapestry.contrib.tree.simple.SimpleTreeModel;
+import org.apache.tapestry.engine.IEngineService;
+import org.apache.tapestry.event.PageDetachListener;
+import org.apache.tapestry.event.PageEvent;
+import org.apache.tapestry.html.BasePage;
+
+/** @author tsv? */
+public abstract class FileSystemTree extends BasePage implements ISelectedFolderSource,
+        ITreeStateListener, PageDetachListener
+{
+    private ITreeSessionStateManager m_objTreeSessionStateManager = null;
+
+    private ITreeDataModel m_objDataModel;
+
+    private ITreeModel m_objModel;
+
+    private Object m_objValue;
+
+    @InjectObject("engine-service:asset")
+    public abstract IEngineService getAssetService();
+
+    /**
+     * Injected
+     * 
+     * @since 4.0
+     */
+    public abstract String getTreeRootDir();
+
+    public void pageDetached(PageEvent event)
+    {
+        m_objDataModel = null;
+        m_objValue = null;
+        m_objTreeSessionStateManager = null;
+    }
+
+    public void initTableModel()
+    {
+        ITreeNode objParent;
+
+        String strRootDir = getTreeRootDir();
+
+        System.out.println("strRootDir = " + strRootDir);
+
+        if (strRootDir == null || "".equals(strRootDir))
+        {
+            objParent = new FileSystem(getAssetService());
+        }
+        else
+        {
+            FolderObject objFolder = new FolderObject(null, new File(strRootDir), true,
+                    getAssetService());
+            objFolder.reload();
+            objParent = objFolder;
+        }
+
+        m_objDataModel = new FileSystemDataModel(objParent);
+        m_objModel = new SimpleTreeModel(m_objDataModel);
+    }
+
+    public Date getCurrentTime()
+    {
+        return new Date();
+    }
+
+    public ITreeModel getTreeModel()
+    {
+        if (m_objDataModel == null)
+        {
+            initTableModel();
+        }
+        return m_objModel;
+    }
+
+    /**
+     * Returns the value.
+     * 
+     * @return Object
+     */
+    public Object getValue()
+    {
+        return m_objValue;
+    }
+
+    /**
+     * Sets the value.
+     * 
+     * @param value
+     *            The value to set
+     */
+    public void setValue(Object value)
+    {
+        m_objValue = value;
+    }
+
+    public INodeRenderFactory getRenderFactory()
+    {
+        return new NodeRenderFactory();
+    }
+
+    public ITreeSessionStateManager getSessionStateManager()
+    {
+        // IPage objPage = getRequestCycle().getPage("contrib:TreeNodeViewPage");
+        // System.out.println("TreeNodeViewPage NamespaceId :
+        // "+objPage.getNamespace().getNamespaceId());
+
+        if (m_objTreeSessionStateManager == null)
+        {
+            String strRootDir = getTreeRootDir();
+            // System.out.println("strRootDir = " + strRootDir);
+
+            m_objTreeSessionStateManager = new FileSystemStateManager(strRootDir, getAssetService());
+        }
+        return m_objTreeSessionStateManager;
+    }
+
+    /**
+     * @see org.apache.tapestry.ajaxworkbench.tree.examples.ISelectedFolderSource#getSelectedFolder()
+     */
+    public Collection getSelectedFolderChildren()
+    {
+        TreeView objTreeView = (TreeView) getComponent("treeView");
+        ITreeStateModel objTreeStateModel = objTreeView.getTreeModel().getTreeStateModel();
+        Object objSelectedNodeUID = objTreeStateModel.getSelectedNode();
+        ITreeNode objSelectedNode = null;
+        if (objSelectedNodeUID != null)
+            objSelectedNode = (ITreeNode) getTreeModel().getTreeDataModel().getObject(
+                    objSelectedNodeUID);
+        else
+        {
+            objSelectedNode = (ITreeNode) getTreeModel().getTreeDataModel().getRoot();
+        }
+        return objSelectedNode.getChildren();
+    }
+
+    /**
+     * @see org.apache.tapestry.contrib.tree.model.ITreeStateListener#treeStateChanged(org.apache.tapestry.contrib.tree.model.TreeStateEvent)
+     */
+    public void treeStateChanged(TreeStateEvent objEvent)
+    {
+        DirectoryTableView objDirectoryTableView = (DirectoryTableView) getComponent("directoryTableView");
+        objDirectoryTableView.resetState();
+    }
+
+    public ITreeStateListener getTreeStateListener()
+    {
+        return this;
+    }
+
+    public ISelectedFolderSource getSelectedFolderSource()
+    {
+        return this;
+    }
+
+    /**
+     * @see org.apache.tapestry.ajaxworkbench.tree.examples.ISelectedFolderSource#getSelectedNodeName()
+     */
+    public String getSelectedNodeName()
+    {
+        TreeView objTreeView = (TreeView) getComponent("treeView");
+        ITreeStateModel objTreeStateModel = objTreeView.getTreeModel().getTreeStateModel();
+        Object objSelectedNodeUID = objTreeStateModel.getSelectedNode();
+        ITreeNode objSelectedNode = null;
+        if (objSelectedNodeUID != null)
+            objSelectedNode = (ITreeNode) getTreeModel().getTreeDataModel().getObject(
+                    objSelectedNodeUID);
+        else
+        {
+            objSelectedNode = (ITreeNode) getTreeModel().getTreeDataModel().getRoot();
+        }
+        return objSelectedNode.toString();
+    }
+
+}
\ No newline at end of file

Added: jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/tree/examples/FileSystemTreeTable.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/tree/examples/FileSystemTreeTable.java?rev=371786&view=auto
==============================================================================
--- jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/tree/examples/FileSystemTreeTable.java (added)
+++ jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/tree/examples/FileSystemTreeTable.java Mon Jan 23 19:04:45 2006
@@ -0,0 +1,235 @@
+// Copyright 2004, 2005, 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.tapestry.ajaxworkbench.tree.examples;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+
+import org.apache.tapestry.ajaxworkbench.tree.examples.fsmodel.FileSystem;
+import org.apache.tapestry.ajaxworkbench.tree.examples.fsmodel.FileSystemDataModel;
+import org.apache.tapestry.ajaxworkbench.tree.examples.fsmodel.FileSystemStateManager;
+import org.apache.tapestry.ajaxworkbench.tree.examples.fsmodel.FolderObject;
+import org.apache.tapestry.ajaxworkbench.tree.examples.fsmodel.IFileSystemTreeNode;
+import org.apache.tapestry.ajaxworkbench.tree.examples.fsmodel.NodeRenderFactory;
+import org.apache.tapestry.annotations.InjectObject;
+import org.apache.tapestry.contrib.table.model.simple.SimpleTableColumn;
+import org.apache.tapestry.contrib.tree.components.INodeRenderFactory;
+import org.apache.tapestry.contrib.tree.components.table.TreeTable;
+import org.apache.tapestry.contrib.tree.model.ITreeDataModel;
+import org.apache.tapestry.contrib.tree.model.ITreeModel;
+import org.apache.tapestry.contrib.tree.model.ITreeModelSource;
+import org.apache.tapestry.contrib.tree.model.ITreeNode;
+import org.apache.tapestry.contrib.tree.model.ITreeSessionStateManager;
+import org.apache.tapestry.contrib.tree.model.ITreeStateListener;
+import org.apache.tapestry.contrib.tree.model.ITreeStateModel;
+import org.apache.tapestry.contrib.tree.model.TreeRowObject;
+import org.apache.tapestry.contrib.tree.model.TreeStateEvent;
+import org.apache.tapestry.contrib.tree.simple.SimpleTreeModel;
+import org.apache.tapestry.engine.IEngineService;
+import org.apache.tapestry.event.PageDetachListener;
+import org.apache.tapestry.event.PageEvent;
+import org.apache.tapestry.html.BasePage;
+
+/** @author mindbridge ? */
+public abstract class FileSystemTreeTable extends BasePage implements ISelectedFolderSource, ITreeStateListener,
+        PageDetachListener
+{
+
+    private ITreeSessionStateManager m_objTreeSessionStateManager = null;
+
+    private ITreeDataModel m_objDataModel;
+
+    private ITreeModel m_objModel;
+
+    private Object m_objValue;
+
+    private ArrayList m_arrTableColumns = null;
+
+    /**
+     * Injected
+     * 
+     * @since 4.0
+     */
+
+    public abstract String getTreeRootDir();
+
+    @InjectObject("engine-service:asset")
+    public abstract IEngineService getAssetService();
+
+    public void pageDetached(PageEvent event)
+    {
+        m_objDataModel = null;
+        m_objValue = null;
+        m_objTreeSessionStateManager = null;
+    }
+
+    public void initTableModel()
+    {
+        ITreeNode objParent;
+        String strRootDir = getTreeRootDir();
+
+        System.out.println("strRootDir = " + strRootDir);
+
+        if (strRootDir == null || "".equals(strRootDir))
+        {
+            objParent = new FileSystem(getAssetService());
+        }
+        else
+        {
+            FolderObject objFolder = new FolderObject(null, new File(strRootDir), true, getAssetService());
+            objFolder.reload();
+            objParent = objFolder;
+        }
+
+        m_objDataModel = new FileSystemDataModel(objParent);
+        m_objModel = new SimpleTreeModel(m_objDataModel);
+    }
+
+    public Date getCurrentTime()
+    {
+        return new Date();
+    }
+
+    public ITreeModel getTreeModel()
+    {
+        if (m_objDataModel == null)
+        {
+            initTableModel();
+        }
+        return m_objModel;
+    }
+
+    /**
+     * Returns the value.
+     * 
+     * @return Object
+     */
+    public Object getValue()
+    {
+        return m_objValue;
+    }
+
+    /**
+     * Sets the value.
+     * 
+     * @param value
+     *            The value to set
+     */
+    public void setValue(Object value)
+    {
+        m_objValue = value;
+    }
+
+    public INodeRenderFactory getRenderFactory()
+    {
+        return new NodeRenderFactory();
+    }
+
+    public ITreeSessionStateManager getSessionStateManager()
+    {
+        if (m_objTreeSessionStateManager == null)
+        {
+            String strRootDir = getTreeRootDir();
+            m_objTreeSessionStateManager = new FileSystemStateManager(strRootDir, getAssetService());
+        }
+        return m_objTreeSessionStateManager;
+    }
+
+    /**
+     * @return
+     */
+    public ArrayList getTableColumns()
+    {
+        if (m_arrTableColumns == null)
+        {
+            m_arrTableColumns = new ArrayList();
+            m_arrTableColumns.add(new SimpleTableColumn("Date", true)
+            {
+
+                private static final long serialVersionUID = -8211004113105081255L;
+
+                public Object getColumnValue(Object objValue)
+                {
+                    TreeRowObject objRowObject = (TreeRowObject)objValue;
+                    // SFObject objSFObject =
+                    // (SFObject)objRowObject.getTreeNode();
+                    IFileSystemTreeNode objFileSystemTreeNode = (IFileSystemTreeNode)objRowObject.getTreeNode();
+                    return objFileSystemTreeNode.getDate();
+                }
+            });
+        }
+        return m_arrTableColumns;
+    }
+
+    /**
+     * @see org.apache.tapestry.ajaxworkbench.tree.examples.ISelectedFolderSource#getSelectedFolder()
+     */
+    public Collection getSelectedFolderChildren()
+    {
+        TreeTable objTreeTable = (TreeTable)getComponent("tree");
+        ITreeModelSource objTreeModelSource = objTreeTable.getTreeModelSource();
+        ITreeStateModel objTreeStateModel = objTreeModelSource.getTreeModel().getTreeStateModel();
+        Object objSelectedNodeUID = objTreeStateModel.getSelectedNode();
+        ITreeNode objSelectedNode = null;
+        if (objSelectedNodeUID != null)
+            objSelectedNode = (ITreeNode)getTreeModel().getTreeDataModel().getObject(objSelectedNodeUID);
+        else
+        {
+            objSelectedNode = (ITreeNode)getTreeModel().getTreeDataModel().getRoot();
+        }
+        return objSelectedNode.getChildren();
+    }
+
+    /**
+     * @see org.apache.tapestry.contrib.tree.model.ITreeStateListener#treeStateChanged(org.apache.tapestry.contrib.tree.model.TreeStateEvent)
+     */
+    public void treeStateChanged(TreeStateEvent objEvent)
+    {
+        DirectoryTableView objDirectoryTableView = (DirectoryTableView)getComponent("directoryTableView");
+        objDirectoryTableView.resetState();
+    }
+
+    public ITreeStateListener getTreeStateListener()
+    {
+        return this;
+    }
+
+    public ISelectedFolderSource getSelectedFolderSource()
+    {
+        return this;
+    }
+
+    /**
+     * @see org.apache.tapestry.ajaxworkbench.tree.examples.ISelectedFolderSource#getSelectedNodeName()
+     */
+    public String getSelectedNodeName()
+    {
+        TreeTable objTreeTable = (TreeTable)getComponent("tree");
+        ITreeModelSource objTreeModelSource = objTreeTable.getTreeModelSource();
+        ITreeStateModel objTreeStateModel = objTreeModelSource.getTreeModel().getTreeStateModel();
+        Object objSelectedNodeUID = objTreeStateModel.getSelectedNode();
+        ITreeNode objSelectedNode = null;
+        if (objSelectedNodeUID != null)
+            objSelectedNode = (ITreeNode)getTreeModel().getTreeDataModel().getObject(objSelectedNodeUID);
+        else
+        {
+            objSelectedNode = (ITreeNode)getTreeModel().getTreeDataModel().getRoot();
+        }
+        return objSelectedNode.toString();
+    }
+
+}

Added: jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/tree/examples/ISelectedFolderSource.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/tree/examples/ISelectedFolderSource.java?rev=371786&view=auto
==============================================================================
--- jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/tree/examples/ISelectedFolderSource.java (added)
+++ jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/tree/examples/ISelectedFolderSource.java Mon Jan 23 19:04:45 2006
@@ -0,0 +1,31 @@
+// Copyright 2004, 2005, 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.tapestry.ajaxworkbench.tree.examples;
+
+import java.util.Collection;
+
+/**
+ * All right reserved. Copyright (c) by Rushmore Digital Ltd. Created on Sep 4,
+ * 2003
+ * 
+ * @author ceco
+ */
+public interface ISelectedFolderSource
+{
+
+    Collection getSelectedFolderChildren();
+
+    String getSelectedNodeName();
+}

Added: jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/tree/examples/SimpleTree.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/tree/examples/SimpleTree.java?rev=371786&view=auto
==============================================================================
--- jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/tree/examples/SimpleTree.java (added)
+++ jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/tree/examples/SimpleTree.java Mon Jan 23 19:04:45 2006
@@ -0,0 +1,105 @@
+// Copyright 2004, 2005 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.ajaxworkbench.tree.examples;
+
+import java.util.Date;
+
+import org.apache.tapestry.contrib.tree.model.ITreeDataModel;
+import org.apache.tapestry.contrib.tree.model.ITreeModel;
+import org.apache.tapestry.contrib.tree.simple.SimpleTreeDataModel;
+import org.apache.tapestry.contrib.tree.simple.SimpleTreeModel;
+import org.apache.tapestry.html.BasePage;
+
+/**
+ * Simple example page.
+ * 
+ * @version $Revision: 244212 $
+ */
+public abstract class SimpleTree extends BasePage
+{
+    private ITreeDataModel treeDataModel;
+
+    private ITreeModel treeModel;
+
+    private Object value;
+
+    public SimpleTree()
+    {
+    }
+
+    public void detach()
+    {
+        super.detach();
+        treeDataModel = null;
+        value = null;
+    }
+
+    public void init()
+    {
+        TestTreeNode objParent = new TestTreeNode("Parent");
+
+        TestTreeNode objChild1 = new TestTreeNode("Child1");
+        TestTreeNode objChild2 = new TestTreeNode("Child2");
+        TestTreeNode objChild3 = new TestTreeNode("Child3");
+
+        objParent.insert(objChild3);
+        objParent.insert(objChild2);
+        objParent.insert(objChild1);
+
+        TestTreeNode objChild31 = new TestTreeNode("Child31");
+        TestTreeNode objChild32 = new TestTreeNode("Child32");
+
+        objChild3.insert(objChild32);
+        objChild3.insert(objChild31);
+
+        treeDataModel = new SimpleTreeDataModel(objParent);
+        treeModel = new SimpleTreeModel(treeDataModel);
+    }
+
+    public Date getCurrentTime()
+    {
+        return new Date();
+    }
+
+    public ITreeModel getTreeModel()
+    {
+        if (treeModel == null)
+        {
+            init();
+        }
+        return treeModel;
+    }
+
+    /**
+     * Returns the value.
+     * 
+     * @return Object
+     */
+    public Object getValue()
+    {
+        return value;
+    }
+
+    /**
+     * Sets the value.
+     * 
+     * @param value
+     *            The value to set
+     */
+    public void setValue(Object value)
+    {
+        this.value = value;
+    }
+}
\ No newline at end of file

Added: jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/tree/examples/TestTreeNode.java
URL: http://svn.apache.org/viewcvs/jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/tree/examples/TestTreeNode.java?rev=371786&view=auto
==============================================================================
--- jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/tree/examples/TestTreeNode.java (added)
+++ jakarta/tapestry/trunk/examples/AjaxWorkbench/src/java/org/apache/tapestry/ajaxworkbench/tree/examples/TestTreeNode.java Mon Jan 23 19:04:45 2006
@@ -0,0 +1,78 @@
+// Copyright 2004, 2005, 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.tapestry.ajaxworkbench.tree.examples;
+
+import org.apache.tapestry.contrib.tree.model.IMutableTreeNode;
+import org.apache.tapestry.contrib.tree.simple.TreeNode;
+
+/**
+ * @author ceco
+ */
+public class TestTreeNode extends TreeNode
+{
+
+    private static final long serialVersionUID = -2513375115143901815L;
+
+    private String m_strValue;
+
+    /**
+     * Constructor for TestTreeNode.
+     */
+    public TestTreeNode(String strValue)
+    {
+        this(null, strValue);
+    }
+
+    /**
+     * Constructor for TestTreeNode.
+     * 
+     * @param parentNode
+     */
+    public TestTreeNode(IMutableTreeNode parentNode, String strValue)
+    {
+        super(parentNode);
+        m_strValue = strValue;
+    }
+
+    public String toString()
+    {
+        return m_strValue;
+    }
+
+    public int hashCode()
+    {
+        return m_strValue.hashCode();
+    }
+
+    public boolean equals(Object objTarget)
+    {
+        if (objTarget == this) return true;
+        if (!(objTarget instanceof TestTreeNode)) return false;
+
+        TestTreeNode objTargetNode = (TestTreeNode)objTarget;
+        return this.getValue().equals(objTargetNode.getValue());
+    }
+
+    /**
+     * Returns the value.
+     * 
+     * @return String
+     */
+    public String getValue()
+    {
+        return m_strValue;
+    }
+
+}



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