/* * 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.util; import java.util.AbstractList; import java.util.Map; import org.apache.cocoon.forms.formmodel.Repeater; import org.apache.cocoon.forms.formmodel.Widget; /** * A <code>List</code> view of a {@link Repeater}, each element of the list being a <code>Map</code> * wrapping a repeater row, as defined by {@link ContainerWidgetAsMap}. * <p> * This implementation of list supports all methods, with the following restrictions: * <ul> * <li>values stored in the list must be <code>Map</code>s, that will be used with {@link ContainerWidgetAsMap#putAll(Map)} * on the <code>Map</code> representation of the repeater rows,</li> * <li>operations that involve testing equality with the list contents (e.g. <code>contains(Object)</code>) will * not function properly, the <code>Map</code> wrapping the rows being created on demand.</li> * </ul> * * @since 2.1.8 * @version $Id$ */ public class RepeaterAsList extends AbstractList { private Repeater repeater; private boolean lowerCase; /** * Create a <code>List<code> view around a repeater. The <code>keysToLowerCase</code> parameter * specifies if <code>Map</code>s wrapping rows should convert input keys to lower case, as * specified by {@link ContainerWidgetAsMap#ContainerWidgetAsMap(AbstractContainerWidget, boolean)}. * * @param repeater the repeater to wrap * @param keysToLowerCase should we convert input keys to lower case? */ public RepeaterAsList(Repeater repeater, boolean keysToLowerCase) { this.repeater = repeater; this.lowerCase = keysToLowerCase; } /** * Same as <code>RepeaterAsList(repeater, false)</code>. */ public RepeaterAsList(Repeater repeater) { this(repeater, false); } /** * Get the repeater widget that is wrapped by this <code>List</code>. * * @return the wrapped {@link Repeater} */ public Repeater getWidget() { return this.repeater; } /** * Get a widget relative to the repeater wrapped by this <code>List</code> * * @param path a widget lookup path * @return the widget pointed to by <code>path</code> or <code>null</code> if it doesn't exist. * @see Widget#lookupWidget(String) */ public Widget getWidget(String path) { return this.repeater.lookupWidget(path); } public Object get(int index) { return new ContainerWidgetAsMap(repeater.getRow(index), lowerCase); } public int size() { return repeater.getSize(); } public Object set(int index, Object o) { if (o == null) { throw new NullPointerException("Cannot set null to a repeater"); } if (!(o instanceof Map)) { throw new IllegalArgumentException("Cannot set a '" + o.getClass().toString() + "' to a repeater"); } Map result = new ContainerWidgetAsMap(repeater.getRow(index)); result.putAll((Map)o); return result; } public void add(int index, Object o) { if (o == null) { throw new NullPointerException("Cannot add null to a repeater"); } if (!(o instanceof Map)) { throw new IllegalArgumentException("Cannot add a '" + o.getClass().toString() + "' to a repeater"); } Repeater.RepeaterRow row = repeater.addRow(index); new ContainerWidgetAsMap(row).putAll((Map)o); } public Object remove(int index) { Map result = new ContainerWidgetAsMap(repeater.getRow(index)); repeater.removeRow(index); return result; } // Not mandated by the abstract class, but will speed up things public void clear() { repeater.clear(); } }