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 org.opencms.search.CmsSearchParameters;
031
032import java.util.Collection;
033import java.util.LinkedList;
034import java.util.List;
035
036/**
037 * A hook on the list of categories of the <code>CmsSearchParameters</code>
038 * (see <code>{@link org.opencms.search.CmsSearchParameters#setCategories(List)}</code>)
039 * that will set the page to display of the search parameters to start (1) whenever
040 * a change in the amount of categories takes place. <p>
041 *
042 * This hook monitors the actions of the <code>{@link org.opencms.workplace.CmsWidgetDialog}</code>:
043 * During a request - response cycle it clears the list (prepareCommit)
044 * of categories and adds all request parameters (actionCommitValue) to the list. <p>
045 *
046 * The strategy here is to save all categories in a backup at "onClear" - time
047 * and then wait until all add operations are finished. This is when the iterator()
048 * method is triggered by the running search (<code>{@link org.opencms.search.CmsSearch#getSearchResult()}</code>).
049 * At that time it is detected wether we have "lost" categories. If this is the
050 * case, the search page will be reset to start. <p>
051 *
052 * <h3>Warning</h3>
053 * This procedure is highly unstable as coupled to the behaviour of CmsWidgetDialog. It
054 * will only be successful if the request parameter "action" has a value in
055 * <ol>
056 *  <li>
057 *   <code>{@link org.opencms.workplace.CmsWidgetDialog#DIALOG_SAVE}</code>
058 *  </li>
059 *  <li>
060 *   <code>{@link org.opencms.workplace.CmsWidgetDialog#DIALOG_BACK}</code>
061 *  </li>
062 *  <li>
063 *   <code>{@link org.opencms.workplace.CmsWidgetDialog#DIALOG_CONTINUE}</code>
064 *  </li>
065 * </ol>
066 *
067 * Search page links (<code>{@link org.opencms.search.CmsSearch#getPageLinks()}</code>)
068 * contain a parameter "action" with value "search" which has to be rewritten to one
069 * of those values or the order of operations on widget - managed collections does not
070 * work together with the detection strategy for category changes used here. <p>
071 *
072 * @since 6.0.0
073 */
074public class CmsHookListSearchCategory extends CmsHookList {
075
076    /** The serial version UID. */
077    private static final long serialVersionUID = 145986432425221213L;
078
079    /** The snapshot (clone) of this list at "clear()" time. **/
080    private List<Object> m_backupCategories;
081
082    /**
083     * @param peer the search parameters to modify upon category modifications.
084     */
085    public CmsHookListSearchCategory(CmsSearchParameters peer) {
086
087        super(peer);
088    }
089
090    /**
091     * @param peer the search parameters to modify upon category modifications
092     *
093     * @param c a collection with all values for this list
094     */
095    public CmsHookListSearchCategory(CmsSearchParameters peer, Collection<String> c) {
096
097        super(peer, c);
098
099    }
100
101    /**
102     * A category has been added: do nothing. <p>
103     *
104     * @see org.opencms.workplace.tools.searchindex.CmsHookList#onAdded(java.lang.Object, int, java.lang.Object)
105     */
106    @Override
107    protected void onAdded(Object peer, int index, Object element) {
108
109        // nop
110    }
111
112    /**
113     * @see org.opencms.workplace.tools.searchindex.CmsHookList#onAdded(java.lang.Object, java.lang.Object)
114     */
115    @Override
116    protected void onAdded(Object peer, Object added) {
117
118        // nop
119    }
120
121    /**
122     * Takes a copy of the current categories contained to a backup list as this
123     * operation is triggered by
124     * <code>{@link org.opencms.workplace.CmsWidgetDialog#ACTION_SAVE}</code>.<p>
125     *
126     * @see org.opencms.workplace.tools.searchindex.CmsHookList#onClear(java.lang.Object)
127     */
128    @Override
129    protected void onClear(Object peer) {
130
131        m_backupCategories = new LinkedList<Object>(this);
132    }
133
134    /**
135     *
136     * @see org.opencms.workplace.tools.searchindex.CmsHookList#onCleared(java.lang.Object)
137     */
138    @Override
139    protected void onCleared(Object peer) {
140
141        // nop
142    }
143
144    /**
145     * Set the search page of the peer Object
146     * (<code>{@link org.opencms.search.CmsSearch#setSearchPage(int)}</code>)
147     * to zero if the internal backup list of categories (taken at clear time which
148     * is triggered by <code>{@link org.opencms.workplace.CmsWidgetDialog#ACTION_SAVE}</code>)
149     * was empty (no restriction) and now categories are contained  or if the new
150     * backup list of categories is no subset of the current categories any
151     * more (more restrictive search than before). <p>
152     *
153     * @see org.opencms.workplace.tools.searchindex.CmsHookList#onGetCall(java.lang.Object, int)
154     */
155    @Override
156    protected void onGetCall(Object peer, int index) {
157
158        // zero categories are all (first condition)
159        if (((m_backupCategories.size() == 0) && (size() != 0)) || !(containsAll(m_backupCategories))) {
160            ((CmsSearchParameters)peer).setSearchPage(1);
161        }
162    }
163
164    /**
165     * @see org.opencms.workplace.tools.searchindex.CmsHookList#onIteratorCall(java.lang.Object)
166     */
167    @Override
168    protected void onIteratorCall(Object peer) {
169
170        // nop
171    }
172
173    /**
174     * A category has been removed: set search page to start page as
175     * new results may / will be smaller. <p>
176     *
177     *
178     * @see org.opencms.workplace.tools.searchindex.CmsHookList#onRemoved(java.lang.Object, int)
179     */
180    @Override
181    protected void onRemoved(Object peer, int index) {
182
183        ((CmsSearchParameters)peer).setSearchPage(1);
184    }
185}