001/*
002 * This library is part of OpenCms -
003 * the Open Source Content Management System
004 *
005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com)
006 *
007 * This library is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 *
012 * This library is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * For further information about Alkacon Software GmbH & Co. KG, please see the
018 * company website: http://www.alkacon.com
019 *
020 * For further information about OpenCms, please see the
021 * project website: http://www.opencms.org
022 *
023 * You should have received a copy of the GNU Lesser General Public
024 * License along with this library; if not, write to the Free Software
025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
026 */
027
028package org.opencms.workplace.tools.searchindex;
029
030import java.util.Collection;
031import java.util.Iterator;
032import java.util.LinkedList;
033
034/**
035 * A list intended for subclassing that triggers "listlet" operations that may
036 * access a on a "peer" object
037 * that is provided by a template method to implement in subclasses. <p>
038 *
039 * This is intended to react on modifications on <code>{@link java.util.List}</code> instances
040 * performed by <code>{@link org.opencms.workplace.CmsWidgetDialogParameter}</code> instances
041 * linked to them. Using normal list implementations makes it impossible to intervene in those
042 * list modification by the widget technology.<p>
043 *
044 * "Listlet" operations are operations that are triggered upon modification of this
045 * list. They are called "on&lt;methodName(&gt;[e]d(&lt;peerObject&gt;, &lt;argList&gt;)"
046 * where &lt;methodName&gt; is the name of the original list operation that took place,
047 * "[e]d" stands for the past (operation took place), &lt;peerObject&gt; is the
048 * given class to perform reactions on (see constructors) and
049 *   &lt;argList&gt; are the arguments of the original list method in that order. <p>
050 *
051 * Currently only the operations used by <code>{@link org.opencms.workplace.CmsWidgetDialog}</code>
052 * (see implementation of <code>{@link org.opencms.workplace.CmsWidgetDialog#actionToggleElement()}</code>)
053 * are supported and sufficient for this purpose. More general usability enforces extending
054 * the pattern shown here. <p>
055 *
056 * @since 6.0.0
057 */
058public abstract class CmsHookList extends LinkedList<String> {
059
060    /** Id for safe serialization. */
061    private static final long serialVersionUID = 3606129489707495072L;
062
063    /** The object operations are made upon. This design cries for 1.5 generics. **/
064    private Object m_peer;
065
066    /**
067     * Creates an empty list. <p>
068     *
069     * Subclasses should increase "safety by design" by narrowing the type of peer.<p>
070     *
071     * @param peer the object reactions on operations shall be made on in the "listlet" methods of subclasses
072     *
073     */
074    public CmsHookList(Object peer) {
075
076        super();
077        m_peer = peer;
078    }
079
080    /**
081     * Creates a list filled with all elements of the given argument. <p>
082     *
083     * Subclasses should increase "safety by design" by narrowing the type of peer.<p>
084     *
085     * @param peer the object reactions on operations shall be made on in the "listlet" methods of subclasses
086     *
087     * @param c a collection with all values for this list
088     */
089    public CmsHookList(Object peer, Collection<String> c) {
090
091        super(c);
092        m_peer = peer;
093    }
094
095    /**
096     *
097     * @see java.util.List#add(int, java.lang.Object)
098     */
099    @Override
100    public void add(int index, String element) {
101
102        super.add(index, element);
103        onAdded(m_peer, index, element);
104
105    }
106
107    /**
108     *
109     * @see java.util.Collection#add(java.lang.Object)
110     */
111    @Override
112    public boolean add(String o) {
113
114        if (super.add(o)) {
115            this.onAdded(m_peer, o);
116            return true;
117        }
118        return false;
119    }
120
121    /**
122     *
123     * @see java.util.Collection#clear()
124     */
125    @Override
126    public void clear() {
127
128        onClear(m_peer);
129        super.clear();
130        onCleared(m_peer);
131    }
132
133    /**
134     *
135     * @see java.util.List#get(int)
136     */
137    @Override
138    public String get(int index) {
139
140        String ret = super.get(index);
141        onGetCall(m_peer, index);
142        return ret;
143    }
144
145    /**
146     *
147     * @see java.util.Collection#iterator()
148     */
149    @Override
150    public Iterator<String> iterator() {
151
152        Iterator<String> it = super.iterator();
153        onIteratorCall(m_peer);
154        return it;
155    }
156
157    /**
158     *
159     * @see java.util.List#remove(int)
160     */
161    @Override
162    public String remove(int index) {
163
164        String ret = null;
165        // get an IndexOutOfBoundsException just like list interfaces contract
166        ret = super.remove(index);
167        return ret;
168    }
169
170    /**
171     * React on the performed operation <code>{@link java.util.List#add(int, java.lang.Object)}</code>
172     * by informing argument peer. <p>
173     *
174     * @param peer the object reactions on operations shall be made on in this "listlet" method
175     * @param index the index the element was added at
176     * @param element the element that was added
177     */
178    protected abstract void onAdded(Object peer, int index, Object element);
179
180    /**
181     * React on the performed operation <code>{@link java.util.List#add(java.lang.Object)}</code>
182     * by informing argument peer. <p>
183     *
184     * @param peer the object reactions on operations shall be made on in this "listlet" method
185     * @param o the element that was successfully added
186     */
187    protected abstract void onAdded(Object peer, Object o);
188
189    /**
190     * React on the operation to come <code>{@link java.util.List#clear()}</code>
191     * by informing argument peer. <p>
192     *
193     * This is called before the actual clear operation takes place.<p>
194     *
195     * @param peer the object reactions on operations shall be made on in this "listlet" method
196     */
197    protected abstract void onClear(Object peer);
198
199    /**
200     * React on the performed operation <code>{@link java.util.List#clear()}</code>
201     * by informing argument peer. <p>
202     *
203     * This is called after the actual clear operation has taken place.<p>
204     *
205     * @param peer the object reactions on operations shall be made on in this "listlet" method
206     */
207    protected abstract void onCleared(Object peer);
208
209    /**
210     * React on the performed operation <code>{@link java.util.List#get(int)}</code>
211     * by informing argument peer. <p>
212     *
213     * Note that the call reult is only obtained in this instance but not given to the
214     * requesting client when this handler is invoked.<p>
215     *
216     * @param peer the object reactions on operations shall be made on in this "listlet" method
217     * @param index the index of the Object to get
218     */
219    protected abstract void onGetCall(Object peer, int index);
220
221    /**
222     * React on the performed operation <code>{@link java.util.List#iterator()}</code>
223     * by informing argument peer. <p>
224     *
225     * Note that the iterator is only obtained but not given to the requesting
226     * client when this handler is invoked.<p>
227     *
228     * @param peer the object reactions on operations shall be made on in this "listlet" method
229     */
230    protected abstract void onIteratorCall(Object peer);
231
232    /**
233     * React on the performed operation <code>{@link java.util.List#remove(int)}</code>
234     * by informing argument peer. <p>
235     *
236     * This is only invoked if the list operation was successful.<p>
237     *
238     * @param peer the object reactions on operations shall be made on in this "listlet" method
239     * @param index the index where the value has been removed
240     */
241    protected abstract void onRemoved(Object peer, int index);
242
243}