| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.cocoon.forms.formmodel; |
| |
| import org.apache.avalon.framework.CascadingRuntimeException; |
| import org.apache.cocoon.forms.FormsException; |
| import org.apache.cocoon.forms.binding.BindingException; |
| import org.apache.cocoon.forms.event.ActionEvent; |
| import org.apache.cocoon.forms.event.ActionListener; |
| |
| /** |
| * Abstract repeater action. Subclasses will typically just self-add an event |
| * handler that will act on the repeater. |
| * |
| * @see RepeaterActionDefinitionBuilder |
| * @version $Id$ |
| */ |
| public abstract class RepeaterActionDefinition extends ActionDefinition { |
| |
| private String name = null; |
| |
| /** |
| * Builds an action whose target repeater is the parent of this widget |
| */ |
| public RepeaterActionDefinition() { |
| } |
| |
| /** |
| * Builds an action whose target is a sibling of this widget |
| * @param repeaterName the name of the repeater |
| */ |
| public RepeaterActionDefinition(String repeaterName) { |
| this.name = repeaterName; |
| } |
| |
| /** |
| * initialize this definition with the other, sort of like a copy constructor |
| */ |
| public void initializeFrom(WidgetDefinition definition) throws Exception { |
| super.initializeFrom(definition); |
| |
| if (!(definition instanceof RepeaterActionDefinition)) { |
| throw new FormsException("Ancestor definition " + definition.getClass().getName() + " is not a RepeaterActionDefinition.", |
| getLocation()); |
| } |
| |
| RepeaterActionDefinition other = (RepeaterActionDefinition) definition; |
| |
| this.name = other.name; |
| } |
| |
| public Widget createInstance() { |
| return new RepeaterAction(this); |
| } |
| |
| /** |
| * Get the name of the repeater on which to act. If <code>null</code>, the repeater |
| * is the parent of the current widget (i.e. actions are in repeater rows). Otherwise, |
| *the repeater is a sibling of the current widget. |
| * |
| * @return the repeater name (can be <code>null</code>). |
| */ |
| public String getRepeaterName() { |
| return this.name; |
| } |
| |
| // --------------------------------------------------------------------------------------------- |
| |
| /** |
| * The definition of a repeater action that deletes the selected rows of a sibling repeater. |
| * <p> |
| * The action listeners attached to this action, if any, are called <em>before</em> the rows |
| * are actually removed |
| */ |
| public static class DeleteRowsActionDefinition extends RepeaterActionDefinition { |
| |
| private String selectName; |
| |
| public DeleteRowsActionDefinition(String repeaterName, String selectName) { |
| super(repeaterName); |
| this.selectName = selectName; |
| } |
| |
| /** |
| * initialize this definition with the other, sort of like a copy constructor |
| */ |
| public void initializeFrom(WidgetDefinition definition) throws Exception { |
| super.initializeFrom(definition); |
| |
| if (!(definition instanceof DeleteRowsActionDefinition)) { |
| throw new FormsException("Ancestor definition " + definition.getClass().getName() + " is not a DeleteRowsActionDefinition.", |
| getLocation()); |
| } |
| |
| DeleteRowsActionDefinition other = (DeleteRowsActionDefinition) definition; |
| |
| this.selectName = other.selectName; |
| } |
| |
| public boolean hasActionListeners() { |
| // we always want to be notified |
| return true; |
| } |
| |
| public void fireActionEvent(ActionEvent event) { |
| // Call action listeners, if any |
| super.fireActionEvent(event); |
| |
| Repeater repeater = ((RepeaterAction) event.getSource()).getRepeater(); |
| |
| // and actually delete the rows |
| for (int i = repeater.getSize() - 1; i >= 0; i--) { |
| Repeater.RepeaterRow row = repeater.getRow(i); |
| if (Boolean.TRUE.equals(row.getChild(this.selectName).getValue())) { |
| repeater.removeRow(i); |
| } |
| } |
| |
| if (repeater instanceof EnhancedRepeater) { |
| try { |
| ((EnhancedRepeater) repeater).refreshPage(); |
| } catch (BindingException e) { |
| throw new CascadingRuntimeException("Error refreshing repeater page", e); |
| } |
| } |
| |
| } |
| } |
| |
| // --------------------------------------------------------------------------------------------- |
| |
| /** |
| * The definition of a repeater action that adds a row to a sibling repeater. |
| */ |
| public static class AddRowActionDefinition extends RepeaterActionDefinition { |
| private int insertRows; |
| |
| public AddRowActionDefinition(String repeaterName, int insertRows) { |
| super(repeaterName); |
| this.insertRows = insertRows; |
| |
| addActionListener(new ActionListener() { |
| public void actionPerformed(ActionEvent event) { |
| Repeater repeater = ((RepeaterAction)event.getSource()).getRepeater(); |
| if (repeater instanceof EnhancedRepeater) { |
| try { |
| ((EnhancedRepeater) repeater).goToPage(((EnhancedRepeater) repeater).getMaxPage()); |
| } catch (BindingException e) { |
| throw new CascadingRuntimeException("Error switching page", e); |
| } |
| } |
| for (int i = 0; i < AddRowActionDefinition.this.insertRows; i++) { |
| repeater.addRow(); |
| } |
| } |
| }); |
| } |
| |
| } |
| |
| // --------------------------------------------------------------------------------------------- |
| |
| /** |
| * The definition of a repeater action that insert rows before the selected rows in a sibling repeater, |
| * or at the end of the repeater if no row is selected. |
| */ |
| public static class InsertRowsActionDefinition extends RepeaterActionDefinition { |
| |
| protected String selectName; |
| |
| /** |
| * initialize this definition with the other, sort of like a copy constructor |
| */ |
| public void initializeFrom(WidgetDefinition definition) throws Exception { |
| super.initializeFrom(definition); |
| |
| if (!(definition instanceof InsertRowsActionDefinition)) { |
| throw new FormsException("Ancestor definition " + definition.getClass().getName() + " is not an InsertRowsActionDefinition.", |
| getLocation()); |
| } |
| |
| InsertRowsActionDefinition other = (InsertRowsActionDefinition) definition; |
| |
| this.selectName = other.selectName; |
| } |
| |
| public InsertRowsActionDefinition(String repeaterName, String selectWidgetName) { |
| super(repeaterName); |
| this.selectName = selectWidgetName; |
| |
| this.addActionListener(new ActionListener() { |
| public void actionPerformed(ActionEvent event) { |
| Repeater repeater = ((RepeaterAction)event.getSource()).getRepeater(); |
| boolean foundSelection = false; |
| for (int i = repeater.getSize() - 1; i >= 0; i--) { |
| Repeater.RepeaterRow row = repeater.getRow(i); |
| Widget selectWidget = row.getChild(selectName); |
| if (Boolean.TRUE.equals(selectWidget.getValue())) { |
| // Add a row |
| repeater.addRow(i); |
| foundSelection = true; |
| } |
| } |
| |
| if (!foundSelection) { |
| // Add a row at the end |
| repeater.addRow(); |
| } |
| } |
| }); |
| } |
| } |
| |
| public static class SortActionDefinition extends RepeaterActionDefinition { |
| protected String field = null; |
| |
| public SortActionDefinition(String repeaterName, String field) { |
| super(repeaterName); |
| this.field = field; |
| |
| this.addActionListener(new ActionListener() { |
| public void actionPerformed(ActionEvent event) { |
| Repeater repeater = ((RepeaterAction)event.getSource()).getRepeater(); |
| if (repeater instanceof EnhancedRepeater) { |
| EnhancedRepeater erep = (EnhancedRepeater) repeater; |
| try { |
| if (repeater.validate()) { |
| erep.sortBy(SortActionDefinition.this.field); |
| } |
| } catch (Exception e) { |
| throw new CascadingRuntimeException("Error switching page", e); |
| } |
| } |
| } |
| }); |
| |
| } |
| } |
| |
| public static class ChangePageActionDefinition extends RepeaterActionDefinition { |
| |
| protected int method; |
| |
| public static final int FIRST = 0; |
| public static final int PREV = 1; |
| public static final int NEXT = 2; |
| public static final int LAST = 3; |
| public static final int CUSTOM = 4; |
| |
| /** |
| * initialize this definition with the other, sort of like a copy constructor |
| */ |
| public void initializeFrom(WidgetDefinition definition) throws Exception { |
| super.initializeFrom(definition); |
| if (definition instanceof ChangePageActionDefinition) { |
| ChangePageActionDefinition other = (ChangePageActionDefinition) definition; |
| this.method = other.method; |
| } else { |
| throw new Exception("Definition to inherit from is not of the right type! (at " + getLocation() + ")"); |
| } |
| } |
| |
| public ChangePageActionDefinition(String repeaterName, int m) { |
| super(repeaterName); |
| |
| this.method = m; |
| |
| this.addActionListener(new ActionListener() { |
| public void actionPerformed(ActionEvent event) { |
| Repeater repeater = ((RepeaterAction)event.getSource()).getRepeater(); |
| if (repeater instanceof EnhancedRepeater) { |
| EnhancedRepeater erep = (EnhancedRepeater) repeater; |
| int page = erep.getCurrentPage(); |
| if (method == FIRST) { |
| page = 0; |
| } else if (method == PREV && page > 0) { |
| page = erep.getCurrentPage() - 1; |
| } else if (method == NEXT && page < erep.getMaxPage()) { |
| page = erep.getCurrentPage() + 1; |
| } else if (method == LAST) { |
| page = erep.getMaxPage(); |
| } else if (method == CUSTOM) { |
| page = erep.getCustomPageWidgetValue(); |
| } else { |
| return; |
| } |
| try { |
| if (repeater.validate()) { |
| erep.goToPage(page); |
| } |
| } catch (Exception e) { |
| throw new CascadingRuntimeException("Error switching page", e); |
| } |
| } |
| } |
| }); |
| } |
| } |
| |
| } |