content: /*
   * This library is part of OpenCms -
   * the Open Source Content Management System
   *
   * Copyright (c) Alkacon Software GmbH & Co. KG (https://www.alkacon.com)
   *
   * This library is free software; you can redistribute it and/or
   * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
   * version 2.1 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
   * Lesser General Public License for more details.
   *
   * For further information about Alkacon Software GmbH & Co. KG, please see the
   * company website: https://www.alkacon.com
   *
   * For further information about OpenCms, please see the
   * project website: https://www.opencms.org
   *
   * You should have received a copy of the GNU Lesser 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 org.opencms.workplace.tools.searchindex;
  
  import java.util.Collection;
  import java.util.Iterator;
  import java.util.LinkedList;
  
  /**
   * A list intended for subclassing that triggers "listlet" operations that may
   * access a on a "peer" object
   * that is provided by a template method to implement in subclasses. <p>
   *
   * This is intended to react on modifications on <code>{@link java.util.List}</code> instances
   * performed by <code>{@link org.opencms.workplace.CmsWidgetDialogParameter}</code> instances
   * linked to them. Using normal list implementations makes it impossible to intervene in those
   * list modification by the widget technology.<p>
   *
   * "Listlet" operations are operations that are triggered upon modification of this
   * list. They are called "on&lt;methodName(&gt;[e]d(&lt;peerObject&gt;, &lt;argList&gt;)"
   * where &lt;methodName&gt; is the name of the original list operation that took place,
   * "[e]d" stands for the past (operation took place), &lt;peerObject&gt; is the
   * given class to perform reactions on (see constructors) and
   *   &lt;argList&gt; are the arguments of the original list method in that order. <p>
   *
   * Currently only the operations used by <code>{@link org.opencms.workplace.CmsWidgetDialog}</code>
   * (see implementation of <code>{@link org.opencms.workplace.CmsWidgetDialog#actionToggleElement()}</code>)
   * are supported and sufficient for this purpose. More general usability enforces extending
   * the pattern shown here. <p>
   *
   * @since 6.0.0
   */
  public abstract class CmsHookList extends LinkedList<String> {
  
      /** Id for safe serialization. */
      private static final long serialVersionUID = 3606129489707495072L;
  
      /** The object operations are made upon. This design cries for 1.5 generics. **/
      private Object m_peer;
  
      /**
       * Creates an empty list. <p>
       *
       * Subclasses should increase "safety by design" by narrowing the type of peer.<p>
       *
       * @param peer the object reactions on operations shall be made on in the "listlet" methods of subclasses
       *
       */
      public CmsHookList(Object peer) {
  
          super();
          m_peer = peer;
      }
  
      /**
       * Creates a list filled with all elements of the given argument. <p>
       *
       * Subclasses should increase "safety by design" by narrowing the type of peer.<p>
       *
       * @param peer the object reactions on operations shall be made on in the "listlet" methods of subclasses
       *
       * @param c a collection with all values for this list
       */
      public CmsHookList(Object peer, Collection<String> c) {
  
          super(c);
          m_peer = peer;
      }
  
      /**
       *
       * @see java.util.List#add(int, java.lang.Object)
       */
      @Override
      public void add(int index, String element) {
  
          super.add(index, element);
          onAdded(m_peer, index, element);
  
      }
  
      /**
       *
       * @see java.util.Collection#add(java.lang.Object)
       */
      @Override
      public boolean add(String o) {
  
          if (super.add(o)) {
              this.onAdded(m_peer, o);
              return true;
          }
          return false;
      }
  
      /**
       *
       * @see java.util.Collection#clear()
       */
      @Override
      public void clear() {
  
          onClear(m_peer);
          super.clear();
          onCleared(m_peer);
      }
  
      /**
       *
       * @see java.util.List#get(int)
       */
      @Override
      public String get(int index) {
  
          String ret = super.get(index);
          onGetCall(m_peer, index);
          return ret;
      }
  
      /**
       *
       * @see java.util.Collection#iterator()
       */
      @Override
      public Iterator<String> iterator() {
  
          Iterator<String> it = super.iterator();
          onIteratorCall(m_peer);
          return it;
      }
  
      /**
       *
       * @see java.util.List#remove(int)
       */
      @Override
      public String remove(int index) {
  
          String ret = null;
          // get an IndexOutOfBoundsException just like list interfaces contract
          ret = super.remove(index);
          return ret;
      }
  
      /**
       * React on the performed operation <code>{@link java.util.List#add(int, java.lang.Object)}</code>
       * by informing argument peer. <p>
       *
       * @param peer the object reactions on operations shall be made on in this "listlet" method
       * @param index the index the element was added at
       * @param element the element that was added
       */
      protected abstract void onAdded(Object peer, int index, Object element);
  
      /**
       * React on the performed operation <code>{@link java.util.List#add(java.lang.Object)}</code>
       * by informing argument peer. <p>
       *
       * @param peer the object reactions on operations shall be made on in this "listlet" method
       * @param o the element that was successfully added
       */
      protected abstract void onAdded(Object peer, Object o);
  
      /**
       * React on the operation to come <code>{@link java.util.List#clear()}</code>
       * by informing argument peer. <p>
       *
       * This is called before the actual clear operation takes place.<p>
       *
       * @param peer the object reactions on operations shall be made on in this "listlet" method
       */
      protected abstract void onClear(Object peer);
  
      /**
       * React on the performed operation <code>{@link java.util.List#clear()}</code>
       * by informing argument peer. <p>
       *
       * This is called after the actual clear operation has taken place.<p>
       *
       * @param peer the object reactions on operations shall be made on in this "listlet" method
       */
      protected abstract void onCleared(Object peer);
  
      /**
       * React on the performed operation <code>{@link java.util.List#get(int)}</code>
       * by informing argument peer. <p>
       *
       * Note that the call reult is only obtained in this instance but not given to the
       * requesting client when this handler is invoked.<p>
       *
       * @param peer the object reactions on operations shall be made on in this "listlet" method
       * @param index the index of the Object to get
       */
      protected abstract void onGetCall(Object peer, int index);
  
      /**
       * React on the performed operation <code>{@link java.util.List#iterator()}</code>
       * by informing argument peer. <p>
       *
       * Note that the iterator is only obtained but not given to the requesting
       * client when this handler is invoked.<p>
       *
       * @param peer the object reactions on operations shall be made on in this "listlet" method
       */
      protected abstract void onIteratorCall(Object peer);
  
      /**
       * React on the performed operation <code>{@link java.util.List#remove(int)}</code>
       * by informing argument peer. <p>
       *
       * This is only invoked if the list operation was successful.<p>
       *
       * @param peer the object reactions on operations shall be made on in this "listlet" method
       * @param index the index where the value has been removed
       */
      protected abstract void onRemoved(Object peer, int index);
  
  }
  