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.modules;
029
030import org.opencms.configuration.CmsConfigurationException;
031import org.opencms.jsp.CmsJspActionElement;
032import org.opencms.main.OpenCms;
033import org.opencms.module.CmsModule;
034import org.opencms.module.CmsModuleDependency;
035import org.opencms.security.CmsSecurityException;
036import org.opencms.util.CmsStringUtil;
037import org.opencms.widgets.CmsInputWidget;
038import org.opencms.widgets.CmsSelectWidget;
039import org.opencms.widgets.CmsSelectWidgetOption;
040import org.opencms.workplace.CmsDialog;
041import org.opencms.workplace.CmsWidgetDialog;
042import org.opencms.workplace.CmsWidgetDialogParameter;
043import org.opencms.workplace.CmsWorkplaceSettings;
044
045import java.text.Collator;
046import java.util.ArrayList;
047import java.util.Collections;
048import java.util.Comparator;
049import java.util.Iterator;
050import java.util.List;
051import java.util.Map;
052
053import javax.servlet.http.HttpServletRequest;
054import javax.servlet.http.HttpServletResponse;
055import javax.servlet.jsp.PageContext;
056
057/**
058 * Class to edit a module dependencies.<p>
059 *
060 * @since 6.0.0
061 */
062public class CmsDependenciesEdit extends CmsWidgetDialog {
063
064    /** The dialog type. */
065    public static final String DIALOG_TYPE = "DependenciesEdit";
066
067    /** localized messages Keys prefix. */
068    public static final String KEY_PREFIX = "modules";
069
070    /** Defines which pages are valid for this dialog. */
071    public static final String[] PAGES = {"page1"};
072
073    /** The module dependency object that is shown on this dialog. */
074    private CmsModuleDependency m_dependency;
075
076    /** Dependency name. */
077    private String m_paramDependency;
078
079    /** Modulename. */
080    private String m_paramModule;
081
082    /**
083     * Public constructor with JSP action element.<p>
084     *
085     * @param jsp an initialized JSP action element
086     */
087    public CmsDependenciesEdit(CmsJspActionElement jsp) {
088
089        super(jsp);
090    }
091
092    /**
093     * Public constructor with JSP variables.<p>
094     *
095     * @param context the JSP page context
096     * @param req the JSP request
097     * @param res the JSP response
098     */
099    public CmsDependenciesEdit(PageContext context, HttpServletRequest req, HttpServletResponse res) {
100
101        this(new CmsJspActionElement(context, req, res));
102    }
103
104    /**
105     * Commits the edited module.<p>
106     */
107    @Override
108    public void actionCommit() {
109
110        List errors = new ArrayList();
111
112        try {
113            // get the correct module
114            String moduleName = getParamModule();
115            CmsModule module = (CmsModule)OpenCms.getModuleManager().getModule(moduleName).clone();
116            // get the current dependencies from the module
117            List oldDependencies = module.getDependencies();
118            // now loop through the dependencies and create the new list of dependencies
119            List newDependencies = new ArrayList();
120            Iterator i = oldDependencies.iterator();
121            while (i.hasNext()) {
122                CmsModuleDependency dep = (CmsModuleDependency)i.next();
123                if (!dep.getName().equals(m_dependency.getName())) {
124                    newDependencies.add(dep);
125                }
126            }
127            // update the dependencies
128            newDependencies.add(m_dependency);
129            module.setDependencies(newDependencies);
130            // update the module
131            OpenCms.getModuleManager().updateModule(getCms(), module);
132            // refresh the list
133            Map objects = (Map)getSettings().getListObject();
134            if (objects != null) {
135                objects.remove(CmsModulesList.class.getName());
136                objects.remove(CmsModulesDependenciesList.class.getName());
137            }
138        } catch (CmsConfigurationException ce) {
139            errors.add(ce);
140        } catch (CmsSecurityException se) {
141            errors.add(se);
142        }
143
144        // set the list of errors to display when saving failed
145        setCommitErrors(errors);
146    }
147
148    /**
149     * Builds the HTML for the dialog form.<p>
150     *
151     * @return the HTML for the dialog form
152     */
153    @Override
154    public String buildDialogForm() {
155
156        StringBuffer result = new StringBuffer(1024);
157
158        try {
159
160            // create the dialog HTML
161            result.append(createDialogHtml(getParamPage()));
162
163        } catch (Throwable t) {
164            // TODO: Error handling
165        }
166        return result.toString();
167    }
168
169    /**
170     * @see org.opencms.workplace.CmsDialog#getCancelAction()
171     */
172    @Override
173    public String getCancelAction() {
174
175        // set the default action
176        setParamPage(getPages().get(0));
177
178        return DIALOG_SET;
179    }
180
181    /**
182     * Gets the module dependency parameter.<p>
183     *
184     * @return the module dependency parameter
185     */
186    public String getParamDependency() {
187
188        return m_paramDependency;
189    }
190
191    /**
192     * Gets the module parameter.<p>
193     *
194     * @return the module parameter
195     */
196    public String getParamModule() {
197
198        return m_paramModule;
199    }
200
201    /**
202     * Sets the module dependency parameter.<p>
203     * @param paramDependency the module dependency parameter
204     */
205    public void setParamDependency(String paramDependency) {
206
207        m_paramDependency = paramDependency;
208    }
209
210    /**
211     * Sets the module parameter.<p>
212     * @param paramModule the module parameter
213     */
214    public void setParamModule(String paramModule) {
215
216        m_paramModule = paramModule;
217    }
218
219    /**
220     * Creates the dialog HTML for all defined widgets of the named dialog (page).<p>
221     *
222     * @param dialog the dialog (page) to get the HTML for
223     * @return the dialog HTML for all defined widgets of the named dialog (page)
224     */
225    @Override
226    protected String createDialogHtml(String dialog) {
227
228        StringBuffer result = new StringBuffer(1024);
229
230        // create table
231        result.append(createWidgetTableStart());
232
233        // show error header once if there were validation errors
234        result.append(createWidgetErrorHeader());
235
236        if (dialog.equals(PAGES[0])) {
237            result.append(dialogBlockStart(key("label.dependencyinformation")));
238            result.append(createWidgetTableStart());
239            result.append(createDialogRowsHtml(0, 1));
240            result.append(createWidgetTableEnd());
241            result.append(dialogBlockEnd());
242        }
243
244        // close table
245        result.append(createWidgetTableEnd());
246
247        return result.toString();
248    }
249
250    /**
251     * Creates the list of widgets for this dialog.<p>
252     */
253    @Override
254    protected void defineWidgets() {
255
256        initModule();
257        setKeyPrefix(KEY_PREFIX);
258
259        addWidget(new CmsWidgetDialogParameter(m_dependency, "name", PAGES[0], new CmsSelectWidget(getModules())));
260        addWidget(new CmsWidgetDialogParameter(m_dependency, "version.version", PAGES[0], new CmsInputWidget()));
261
262    }
263
264    /**
265     * @see org.opencms.workplace.CmsWidgetDialog#getPageArray()
266     */
267    @Override
268    protected String[] getPageArray() {
269
270        return PAGES;
271    }
272
273    /**
274     * @see org.opencms.workplace.CmsWorkplace#initMessages()
275     */
276    @Override
277    protected void initMessages() {
278
279        // add specific dialog resource bundle
280        addMessages(Messages.get().getBundleName());
281        // add default resource bundles
282        super.initMessages();
283    }
284
285    /**
286     * Initializes the module  to work with depending on the dialog state and request parameters.<p>
287     */
288    protected void initModule() {
289
290        Object o;
291        CmsModule module;
292
293        // first get the correct module
294        if (CmsStringUtil.isNotEmpty(m_paramModule)) {
295            module = (CmsModule)OpenCms.getModuleManager().getModule(m_paramModule).clone();
296        } else {
297            // create a new module
298            module = new CmsModule();
299        }
300
301        // now try to get the dependency
302        if (CmsStringUtil.isEmpty(getParamAction()) || CmsDialog.DIALOG_INITIAL.equals(getParamAction())) {
303            o = null;
304        } else {
305            // this is not the initial call, get module dependency from session
306            o = getDialogObject();
307        }
308
309        if (!(o instanceof CmsModuleDependency)) {
310            if (m_paramDependency == null) {
311                // there was no parameter given, so create a new, empty dependency
312                m_dependency = new CmsModuleDependency();
313            } else {
314                // create a new module dependency by reading it from the module
315                List dependencies = module.getDependencies();
316                m_dependency = new CmsModuleDependency();
317                if ((dependencies != null) && (dependencies.size() > 0)) {
318                    Iterator i = dependencies.iterator();
319                    while (i.hasNext()) {
320                        CmsModuleDependency dependency = (CmsModuleDependency)i.next();
321                        if (dependency.getName().equals(m_paramDependency)) {
322                            m_dependency = dependency;
323                        }
324                    }
325                }
326            }
327
328        } else {
329            // reuse module dependency stored in session
330            m_dependency = (CmsModuleDependency)o;
331        }
332
333    }
334
335    /**
336     * @see org.opencms.workplace.CmsWorkplace#initWorkplaceRequestValues(org.opencms.workplace.CmsWorkplaceSettings, javax.servlet.http.HttpServletRequest)
337     */
338    @Override
339    protected void initWorkplaceRequestValues(CmsWorkplaceSettings settings, HttpServletRequest request) {
340
341        // set the dialog type
342        setParamDialogtype(DIALOG_TYPE);
343
344        super.initWorkplaceRequestValues(settings, request);
345
346        // save the current state of the module (may be changed because of the widget values)
347        setDialogObject(m_dependency);
348    }
349
350    /**
351     * @see org.opencms.workplace.CmsWidgetDialog#validateParamaters()
352     */
353    @Override
354    protected void validateParamaters() throws Exception {
355
356        String moduleName = getParamModule();
357        // check module
358        CmsModule module = OpenCms.getModuleManager().getModule(moduleName);
359        if (module == null) {
360            throw new Exception();
361        }
362        // check dependency
363        if (!isNewDependency()) {
364            Iterator it = module.getDependencies().iterator();
365            while (it.hasNext()) {
366                CmsModuleDependency dep = (CmsModuleDependency)it.next();
367                if (dep.getName().equals(getParamDependency())) {
368                    // dependency found
369                    return;
370                }
371            }
372            throw new Exception();
373        }
374    }
375
376    /**
377     * Get the list of all modules available.<p>
378     *
379     * @return list of module names
380     */
381    private List getModules() {
382
383        List retVal = new ArrayList();
384        // get all modules
385        Iterator i = OpenCms.getModuleManager().getModuleNames().iterator();
386        // add them to the list of modules
387        while (i.hasNext()) {
388            String moduleName = (String)i.next();
389            if (moduleName.equals(getParamDependency())) {
390                // check for the preselection
391                retVal.add(new CmsSelectWidgetOption(moduleName, true));
392            } else {
393                retVal.add(new CmsSelectWidgetOption(moduleName, false));
394            }
395        }
396        Collections.sort(retVal, new Comparator() {
397
398            /** Collator used / wrapped */
399            private Collator m_collator = Collator.getInstance(getLocale());
400
401            /**
402             * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
403             */
404            public int compare(Object arg0, Object arg1) {
405
406                CmsSelectWidgetOption o1 = (CmsSelectWidgetOption)arg0;
407                CmsSelectWidgetOption o2 = (CmsSelectWidgetOption)arg1;
408                return m_collator.compare(o1.getOption(), o2.getOption());
409            }
410        });
411        return retVal;
412
413    }
414
415    /**
416     * Checks if the new dependency dialog has to be displayed.<p>
417     *
418     * @return <code>true</code> if the new dependency dialog has to be displayed
419     */
420    private boolean isNewDependency() {
421
422        return getCurrentToolPath().equals("/modules/edit/dependencies/new");
423    }
424}