001/*
002 * File   : $Source$
003 * Date   : $Date$
004 * Version: $Revision$
005 *
006 * This library is part of OpenCms -
007 * the Open Source Content Management System
008 *
009 * Copyright (C) 2002 - 2009 Alkacon Software (https://www.alkacon.com)
010 *
011 * This library is free software; you can redistribute it and/or
012 * modify it under the terms of the GNU Lesser General Public
013 * License as published by the Free Software Foundation; either
014 * version 2.1 of the License, or (at your option) any later version.
015 *
016 * This library is distributed in the hope that it will be useful,
017 * but WITHOUT ANY WARRANTY; without even the implied warranty of
018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
019 * Lesser General Public License for more details.
020 *
021 * For further information about Alkacon Software, please see the
022 * company website: https://www.alkacon.com
023 *
024 * For further information about OpenCms, please see the
025 * project website: https://www.opencms.org
026 *
027 * You should have received a copy of the GNU Lesser General Public
028 * License along with this library; if not, write to the Free Software
029 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
030 */
031
032package org.opencms.workplace.tools.searchindex.sourcesearch;
033
034import org.opencms.file.CmsProject;
035import org.opencms.jsp.CmsJspActionElement;
036import org.opencms.main.CmsException;
037import org.opencms.main.OpenCms;
038import org.opencms.search.CmsSearchIndex;
039import org.opencms.search.solr.CmsSolrIndex;
040import org.opencms.util.CmsStringUtil;
041import org.opencms.widgets.CmsCheckboxWidget;
042import org.opencms.widgets.CmsComboWidget;
043import org.opencms.widgets.CmsInputWidget;
044import org.opencms.widgets.CmsSelectWidget;
045import org.opencms.widgets.CmsSelectWidgetOption;
046import org.opencms.widgets.CmsTypeComboWidget;
047import org.opencms.widgets.CmsVfsFileWidget;
048import org.opencms.workplace.CmsWidgetDialog;
049import org.opencms.workplace.CmsWidgetDialogParameter;
050import org.opencms.workplace.CmsWorkplace;
051import org.opencms.workplace.CmsWorkplaceSettings;
052import org.opencms.workplace.tools.CmsToolDialog;
053import org.opencms.workplace.tools.CmsToolManager;
054
055import java.io.IOException;
056import java.util.ArrayList;
057import java.util.HashMap;
058import java.util.LinkedList;
059import java.util.List;
060import java.util.Locale;
061import java.util.Map;
062
063import jakarta.servlet.ServletException;
064import jakarta.servlet.http.HttpServletRequest;
065import jakarta.servlet.http.HttpServletResponse;
066import jakarta.servlet.jsp.PageContext;
067
068/**
069 * This dialog provides search and replace functionality.<p>
070 *
071 * @since 9.0.0
072 */
073public class CmsSourceSearchDialog extends CmsWidgetDialog {
074
075    /** Localized messages Keys prefix. */
076    public static final String KEY_PREFIX = "sourcesearch";
077
078    /** Defines which pages are valid for this dialog. */
079    public static final String[] PAGES = {"page1"};
080
081    /** The widget mapped data container. */
082    private CmsSearchReplaceSettings m_settings;
083
084    /** Signals whether Solr search is enabled or not. */
085    private boolean m_solrEnabled;
086
087    /**
088     * Public constructor with JSP action element.<p>
089     *
090     * @param jsp an initialized JSP action element
091     */
092    public CmsSourceSearchDialog(final CmsJspActionElement jsp) {
093
094        super(jsp);
095    }
096
097    /**
098     * Public constructor with JSP variables.<p>
099     *
100     * @param context the JSP page context
101     * @param req the JSP request
102     * @param res the JSP response
103     */
104    public CmsSourceSearchDialog(
105        final PageContext context,
106        final HttpServletRequest req,
107        final HttpServletResponse res) {
108
109        this(new CmsJspActionElement(context, req, res));
110
111    }
112
113    /**
114     * @see org.opencms.workplace.CmsWidgetDialog#actionCommit()
115     */
116    @Override
117    public void actionCommit() throws IOException, ServletException {
118
119        List<Throwable> errors = new ArrayList<Throwable>();
120        Map<String, String[]> params = new HashMap<String, String[]>();
121        // set style to display report in correct layout
122        params.put(PARAM_STYLE, new String[] {CmsToolDialog.STYLE_NEW});
123        // set close link to get back to overview after finishing the import
124        params.put(PARAM_CLOSELINK, new String[] {CmsToolManager.linkForToolPath(getJsp(), "/sourcesearch")});
125        // redirect to the report output JSP
126        getToolManager().jspForwardPage(
127            this,
128            CmsWorkplace.PATH_WORKPLACE + "admin/searchindex/sourcesearch/sourcesearch.jsp",
129            params);
130        // set the list of errors to display when saving failed
131        setCommitErrors(errors);
132    }
133
134    /**
135     * @see org.opencms.workplace.CmsWidgetDialog#createDialogHtml(java.lang.String)
136     */
137    @Override
138    protected String createDialogHtml(final String dialog) {
139
140        StringBuffer result = new StringBuffer(1024);
141        // create table
142        result.append(createWidgetTableStart());
143        // show error header once if there were validation errors
144        result.append(createWidgetErrorHeader());
145        // create export file name block
146        result.append(
147            createWidgetBlockStart(
148                key(org.opencms.workplace.tools.searchindex.Messages.GUI_SOURCESEARCH_ADMIN_TOOL_BLOCK_0)));
149        if (m_solrEnabled) {
150            result.append(createDialogRowsHtml(0, 9));
151        } else {
152            result.append(createDialogRowsHtml(0, 8));
153        }
154        result.append(createWidgetBlockEnd());
155        // close table
156        result.append(createWidgetTableEnd());
157        return result.toString();
158    }
159
160    /**
161     * @see org.opencms.workplace.CmsWidgetDialog#defineWidgets()
162     */
163    @Override
164    protected void defineWidgets() {
165
166        m_solrEnabled = isSolrEnabled();
167
168        // initialize the settings object to use for the dialog
169        initSettingsObject();
170        setKeyPrefix(KEY_PREFIX);
171        CmsVfsFileWidget vfsw = new CmsVfsFileWidget(false, getCms().getRequestContext().getSiteRoot());
172        addWidget(new CmsWidgetDialogParameter(m_settings, "paths", "/", PAGES[0], vfsw, 1, 50));
173        addWidget(new CmsWidgetDialogParameter(m_settings, "types", "", PAGES[0], new CmsTypeComboWidget(), 0, 1));
174        // Get list of available locales
175        List<CmsSelectWidgetOption> options = new ArrayList<CmsSelectWidgetOption>();
176        for (final Locale locale : OpenCms.getLocaleManager().getAvailableLocales()) {
177            CmsSelectWidgetOption option = new CmsSelectWidgetOption(locale.toString());
178            options.add(option);
179        }
180        addWidget(new CmsWidgetDialogParameter(m_settings, "locale", "", PAGES[0], new CmsComboWidget(options), 1, 1));
181        addWidget(
182            new CmsWidgetDialogParameter(
183                m_settings,
184                "onlyContentValues",
185                "false",
186                PAGES[0],
187                new CmsCheckboxWidget(),
188                1,
189                1));
190        addWidget(new CmsWidgetDialogParameter(m_settings, "xpath", "", PAGES[0], new CmsInputWidget(), 0, 1));
191        CmsSelectWidget indexOptions = new CmsSelectWidget(getSolrIndexOptions());
192        addWidget(new CmsWidgetDialogParameter(m_settings, "source", "", PAGES[0], indexOptions, 1, 1));
193        if (m_solrEnabled) {
194            addWidget(new CmsWidgetDialogParameter(m_settings, "query", "", PAGES[0], new CmsInputWidget(), 1, 1));
195        }
196        addWidget(new CmsWidgetDialogParameter(m_settings, "searchpattern", "", PAGES[0], new CmsInputWidget(), 1, 1));
197        addWidget(new CmsWidgetDialogParameter(m_settings, "replacepattern", "", PAGES[0], new CmsInputWidget(), 1, 1));
198        CmsSelectWidget projectOptions = new CmsSelectWidget(getProjectSelections());
199        String currProject = getCms().getRequestContext().getCurrentProject().getName();
200        addWidget(new CmsWidgetDialogParameter(m_settings, "project", currProject, PAGES[0], projectOptions, 1, 1));
201    }
202
203    /**
204     * @see org.opencms.workplace.CmsWidgetDialog#getPageArray()
205     */
206    @Override
207    protected String[] getPageArray() {
208
209        return PAGES;
210    }
211
212    /**
213     * @see org.opencms.workplace.CmsWorkplace#initMessages()
214     */
215    @Override
216    protected void initMessages() {
217
218        // add specific dialog resource bundle
219        addMessages(Messages.get().getBundleName());
220        super.initMessages();
221    }
222
223    /**
224     * Initializes the settings object.<p>
225     */
226    protected void initSettingsObject() {
227
228        Object o;
229        if (CmsStringUtil.isEmpty(getParamAction())) {
230            o = new CmsSearchReplaceSettings();
231        } else {
232            // this is not the initial call, get the job object from session
233            o = getDialogObject();
234        }
235
236        if (o == null) {
237            // create a new export handler object
238            m_settings = new CmsSearchReplaceSettings();
239        } else {
240            // reuse export handler object stored in session
241            m_settings = (CmsSearchReplaceSettings)o;
242        }
243
244    }
245
246    /**
247     * @see org.opencms.workplace.CmsWidgetDialog#initWorkplaceRequestValues(org.opencms.workplace.CmsWorkplaceSettings, jakarta.servlet.http.HttpServletRequest)
248     */
249    @Override
250    protected void initWorkplaceRequestValues(final CmsWorkplaceSettings settings, final HttpServletRequest request) {
251
252        // initialize parameters and dialog actions in super implementation
253        super.initWorkplaceRequestValues(settings, request);
254
255        // save the current state of the export handler (may be changed because of the widget values)
256        setDialogObject(m_settings);
257    }
258
259    /**
260     * Returns a list with the available projects of the current user.<p>
261     *
262     * @return a list with the available projects of the current user.
263     */
264    private List<CmsSelectWidgetOption> getProjectSelections() {
265
266        List<CmsSelectWidgetOption> result = new LinkedList<CmsSelectWidgetOption>();
267        List<CmsProject> projects = null;
268        try {
269            projects = OpenCms.getOrgUnitManager().getAllAccessibleProjects(getCms(), "", true);
270        } catch (CmsException e) {
271            return result;
272        }
273
274        boolean first = true;
275        for (CmsProject project : projects) {
276            if (!project.getName().equals(CmsProject.ONLINE_PROJECT_NAME)) {
277                first = false;
278                result.add(new CmsSelectWidgetOption(project.getName(), first, project.getName()));
279            }
280        }
281        return result;
282    }
283
284    /**
285     * Returns select options for all configures Solr Offline indexes.<p>
286     *
287     * @return select options for all configures Solr Offline indexes
288     */
289    private List<CmsSelectWidgetOption> getSolrIndexOptions() {
290
291        List<CmsSelectWidgetOption> result = new ArrayList<CmsSelectWidgetOption>();
292        result.add(
293            new CmsSelectWidgetOption(CmsSearchReplaceSettings.VFS, true, CmsSearchReplaceSettings.VFS.toUpperCase()));
294        if (OpenCms.getSearchManager().getSolrServerConfiguration().isEnabled()) {
295            for (CmsSearchIndex index : OpenCms.getSearchManager().getAllSolrIndexes()) {
296                if (CmsSearchIndex.REBUILD_MODE_OFFLINE.equals(index.getRebuildMode())) {
297                    result.add(new CmsSelectWidgetOption(index.getName(), false, index.getName()));
298                }
299            }
300        }
301        return result;
302    }
303
304    /**
305     * Returns <code>true</code> if Solr search is enabled.<p>
306     *
307     * @return <code>true</code> if Solr search is enabled
308     */
309    private boolean isSolrEnabled() {
310
311        boolean solrEnabled = OpenCms.getSearchManager().getSolrServerConfiguration().isEnabled();
312        CmsSolrIndex solrIndex = OpenCms.getSearchManager().getIndexSolr(CmsSolrIndex.DEFAULT_INDEX_NAME_OFFLINE);
313        return solrEnabled && (solrIndex != null);
314    }
315}