/* * FreeMarker: a tool that allows Java programs to generate HTML * output using templates. * Copyright (C) 1998-2004 Benjamin Geer * Email: beroul@users.sourceforge.net * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ package freemarker.template; import java.io.Serializable; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** * <p> * A simple implementation of the {@link TemplateListModel2} interface, using an * underlying <code>List</code> implementation. * </p> * * <p> * A <code>SimpleList</code> can act as a cache for another * <code>TemplateListModel</code>, e.g. one that gets data from a database. When * passed another {@link TemplateListModel} as an argument to its constructor or * to its {@link #copy(TemplateListModel)} method, the <code>SimpleList</code> * immediately copies all the elements and discards the * <code>TemplateListModel</code>. * </p> * * <p> * All the public methods in this implementation are synchronized. * </p> * * <p> * Note that as of 1.8, this model has been retrofitted to the * {@link TemplateListModel2} interface. * </p> * * @version $Id: SimpleList.java 1080 2005-08-28 10:18:09Z run2000 $ * @see SimpleHash * @see SimpleScalar * @see SimpleNumber */ public class SimpleList implements TemplateListModel2, TemplateIndexedModel, TemplateObjectModel, Serializable { /** * The contents of this <code>SimpleList</code> are stored in this * <code>List</code> object. * * @serial The <code>List</code> that this <code>SimpleList</code> wraps. */ protected List list; /** Serialization id, for future compatibility. */ private static final long serialVersionUID = 2831161847625458436L; /** * Constructs an empty <code>SimpleList</code>. */ public SimpleList() { list = new ArrayList(); } /** * Constructs a <code>SimpleList</code> from the given <code>List</code>. A * defensive copy of the list is made. * * @param list * the list of values to be copied into this * <code>SimpleList</code> * @throws NullPointerException * the list value is null */ public SimpleList(List list) { this.list = new ArrayList(list); } /** * Constructs a <code>SimpleList</code> from the given <code>Array</code> of * {@link TemplateModel}s. * * @param arr * the array to be copied into the underlying <code>List</code>. * @throws NullPointerException * the array to be copied is null */ public SimpleList(TemplateModel[] arr) { copy(arr); } /** * Constructs a <code>SimpleList</code>, copying into it the values from * another {@link TemplateListModel}. * * @param listToCopy * the list to be copied into this one. * @throws TemplateModelException * something went wrong while copying the given list into the * <code>SimpleList</code>. * @throws NullPointerException * the list to be copied is null */ public SimpleList(TemplateListModel listToCopy) throws TemplateModelException { copy(listToCopy); } /** * Constructs a <code>SimpleList</code>, copying into it the values from * another {@link TemplateListModel2}. * * @param listToCopy * the list to be copied into this one. * @throws TemplateModelException * something went wrong while copying the given list into the * <code>SimpleList</code>. * @throws NullPointerException * the list to be copied is null */ public SimpleList(TemplateListModel2 listToCopy) throws TemplateModelException { copy(listToCopy); } /** * Removes all the elements from this <code>SimpleList</code>. */ public synchronized void clear() { list.clear(); } /** * Discards the contents of this <code>SimpleList</code>, and copies into it * the values from a {@link TemplateListModel} object. * * @param listToCopy * the list to be copied into this one. * @throws TemplateModelException * something went wrong while copying the given list into the * <code>SimpleList</code>. * @throws NullPointerException * the list to be copied is null */ public synchronized void copy(TemplateListModel listToCopy) throws TemplateModelException { List newList = new ArrayList(); if (!listToCopy.isRewound()) { listToCopy.rewind(); } while (listToCopy.hasNext()) { newList.add(listToCopy.next()); } this.list = newList; } /** * Discards the contents of this <code>SimpleList</code>, and copies into it * the values from another {@link TemplateListModel2}. * * @param listToCopy * the list to be copied into this one. * @throws TemplateModelException * something went wrong while copying the given list into the * <code>SimpleList</code>. * @throws NullPointerException * the list to be copied is null */ public synchronized void copy(TemplateListModel2 listToCopy) throws TemplateModelException { TemplateIteratorModel iterator = listToCopy.templateIterator(); List newList = new ArrayList(); while (iterator.hasNext()) { newList.add(iterator.next()); } this.list = newList; } /** * Discards the contents of this <code>SimpleList</code>, and copies into it * the values from the given <code>Array</code> of {@link TemplateModel}s. * * @param arr * the array to be copied into the underlying list. * @throws NullPointerException * the array to be copied is null */ public synchronized void copy(TemplateModel[] arr) { List newList = new ArrayList(arr.length); for (int i = 0; i < arr.length; i++) { newList.add(arr[i]); } this.list = newList; } /** * Is the underlying <code>List</code> empty? * * @return <code>true</code> if the list is empty, otherwise * <code>false</code> */ public synchronized boolean isEmpty() throws TemplateModelException { return list.isEmpty(); } /** * Adds a {@link TemplateModel} to the end of this <code>SimpleList</code>. * * @param element * the <code>TemplateModel</code> to be added. */ public synchronized void add(TemplateModel element) { list.add(element); } /** * Adds a string to the end of this <code>SimpleList</code>, by wrapping the * string in a {@link FastScalar}. * * @param s * the <code>String</code> to be added. */ public synchronized void add(String s) { add(new FastScalar(s)); } /** * Adds a number to the end of this <code>SimpleList</code>, by wrapping the * string in a {@link FastNumber}. * * @param n * the <code>Number</code> to be added. */ public synchronized void add(Number n) { add(new FastNumber(n)); } /** * Adds a number to the end of this <code>SimpleList</code>, by wrapping the * string in a {@link FastNumber}. * * @param n * the <code>Number</code> to be added. */ public synchronized void add(long n) { add(new FastNumber(n)); } /** * Adds a boolean to the end of this <code>SimpleList</code>, by wrapping * the boolean in a {@link FastBoolean}. * * @param bool * the boolean to be added. */ public synchronized void add(boolean bool) { add(FastBoolean.getInstance(bool)); } /** * Retrieves an iterator to iterate over this list. * * @return an iterator to iterate over the current list. * @throws TemplateModelException * the next item in the list can't be retrieved, or no next item * exists. */ public synchronized TemplateIteratorModel templateIterator() throws TemplateModelException { return new FastIterator(list); } /** * Returns the used iterator to the list model. * * @param iterator * the iterator to be returned to the object pool, if any */ public void releaseIterator(TemplateIteratorModel iterator) { // Do nothing. } /** * Retrieves the specified item from the list. * * @param index * the index of the item to be retrieved. * @return the specified index in the list. * @throws TemplateModelException * the specified item in the list can't be retrieved, or the * index is out of bounds. */ public synchronized TemplateModel getAtIndex(long index) throws TemplateModelException { if (index >= list.size()) throw new TemplateModelException("IndexOutOfBounds(" + index + ')'); return (TemplateModel) list.get((int) index); } /** * Return an unmodifiable copy of the underlying <code>List</code> object * for manipulation by the <code>freemarker.ext.beans</code> package. * * @return an unmodifiable view of the underlying <code>List</code> object */ public synchronized Object getAsObject() throws TemplateModelException { return Collections.unmodifiableList(list); } /** * Retrieve the value of this object as a <code>String</code>. */ public synchronized String toString() { return list.toString(); } /** * Tests this object for equality with the given object. * * @param o * the object to be compared with * @return <code>true</code> if the objects are equal, otherwise * <code>false</code> */ public synchronized boolean equals(Object o) { if (this == o) { return true; } if (!(o instanceof SimpleList)) { return false; } final SimpleList simpleList = (SimpleList) o; return list.equals(simpleList.list); } /** * Return the hash value for this object. * * @return the hash code corresponding to the value of this object */ public synchronized int hashCode() { return list.hashCode() + 17; } }