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.db.CmsExportPoint;
031import org.opencms.file.types.CmsResourceTypeFolder;
032import org.opencms.jsp.CmsJspActionElement;
033import org.opencms.main.CmsException;
034import org.opencms.main.OpenCms;
035import org.opencms.module.CmsModule;
036import org.opencms.util.CmsStringUtil;
037import org.opencms.workplace.CmsDialog;
038import org.opencms.workplace.CmsWidgetDialog;
039import org.opencms.workplace.CmsWorkplace;
040import org.opencms.workplace.CmsWorkplaceSettings;
041
042import java.util.List;
043import java.util.Map;
044import java.util.Set;
045import java.util.StringTokenizer;
046
047import javax.servlet.http.HttpServletRequest;
048import javax.servlet.http.HttpServletResponse;
049import javax.servlet.jsp.PageContext;
050
051/**
052 * Base class to edit an exiting module.<p>
053 *
054 * @since 6.0.0
055 */
056public class CmsModulesEditBase extends CmsWidgetDialog {
057
058    /** localized messages Keys prefix. */
059    public static final String KEY_PREFIX = "modules";
060
061    /** The dialog type. */
062    public static final String DIALOG_TYPE = "ModulesEdit";
063
064    /** Defines which pages are valid for this dialog. */
065    public static final String[] PAGES = {"page1"};
066
067    /** Classes folder within the module. */
068    public static final String PATH_CLASSES = "classes/";
069
070    /** Elements folder within the module. */
071    public static final String PATH_ELEMENTS = "elements/";
072
073    /** Lib folder within the module. */
074    public static final String PATH_LIB = "lib/";
075
076    /** Resources folder within the module. */
077    public static final String PATH_RESOURCES = "resources/";
078
079    /** Schemas folder within the module. */
080    public static final String PATH_SCHEMAS = "schemas/";
081
082    /** Template folder within the module. */
083    public static final String PATH_TEMPLATES = "templates/";
084
085    /** The formatters folder within the module. */
086    public static final String PATH_FORMATTERS = "formatters/";
087
088    /** The module object that is edited on this dialog. */
089    protected CmsModule m_module;
090
091    /** Module name. */
092    protected String m_paramModule;
093
094    /**
095     * Public constructor with JSP action element.<p>
096     *
097     * @param jsp an initialized JSP action element
098     */
099    public CmsModulesEditBase(CmsJspActionElement jsp) {
100
101        super(jsp);
102    }
103
104    /**
105     * Public constructor with JSP variables.<p>
106     *
107     * @param context the JSP page context
108     * @param req the JSP request
109     * @param res the JSP response
110     */
111    public CmsModulesEditBase(PageContext context, HttpServletRequest req, HttpServletResponse res) {
112
113        this(new CmsJspActionElement(context, req, res));
114    }
115
116    /**
117     * Commits the edited module.<p>
118     */
119    @Override
120    public void actionCommit() {
121
122        if (!hasCommitErrors()) {
123            //check if we have to update an existing module or to create a new one
124            Set<String> moduleNames = OpenCms.getModuleManager().getModuleNames();
125            if (moduleNames.contains(m_module.getName())) {
126                // update the module information
127                try {
128                    OpenCms.getModuleManager().updateModule(getCms(), m_module);
129                } catch (CmsException e) {
130                    addCommitError(e);
131                }
132            } else {
133                try {
134                    m_module = createModuleFolders((CmsModule)m_module.clone());
135                    OpenCms.getModuleManager().addModule(getCms(), m_module);
136                } catch (CmsException e) {
137                    addCommitError(e);
138                }
139            }
140        }
141
142        if (!hasCommitErrors()) {
143            // refresh the list
144            Map<?, ?> objects = (Map<?, ?>)getSettings().getListObject();
145            if (objects != null) {
146                objects.remove(CmsModulesList.class.getName());
147            }
148        }
149    }
150
151    /**
152     * @see org.opencms.workplace.CmsDialog#getCancelAction()
153     */
154    @Override
155    public String getCancelAction() {
156
157        // set the default action
158        setParamPage(getPages().get(0));
159
160        return DIALOG_SET;
161    }
162
163    /**
164     * Gets the module parameter.<p>
165     *
166     * @return the module parameter
167     */
168    public String getParamModule() {
169
170        return m_paramModule;
171    }
172
173    /**
174     * Sets the module parameter.<p>
175     * @param paramModule the module parameter
176     */
177    public void setParamModule(String paramModule) {
178
179        m_paramModule = paramModule;
180    }
181
182    /**
183     * Creates the list of widgets for this dialog.<p>
184     */
185    @Override
186    protected void defineWidgets() {
187
188        initModule();
189        setKeyPrefix(KEY_PREFIX);
190    }
191
192    /**
193     * @see org.opencms.workplace.CmsWidgetDialog#getPageArray()
194     */
195    @Override
196    protected String[] getPageArray() {
197
198        return PAGES;
199    }
200
201    /**
202     * @see org.opencms.workplace.CmsWorkplace#initMessages()
203     */
204    @Override
205    protected void initMessages() {
206
207        // add specific dialog resource bundle
208        addMessages(Messages.get().getBundleName());
209        // add default resource bundles
210        super.initMessages();
211    }
212
213    /**
214     * Initializes the module  to work with depending on the dialog state and request parameters.<p>
215     */
216    protected void initModule() {
217
218        Object o;
219
220        if (CmsStringUtil.isEmpty(getParamAction()) || CmsDialog.DIALOG_INITIAL.equals(getParamAction())) {
221            // this is the initial dialog call
222            if (CmsStringUtil.isNotEmpty(m_paramModule)) {
223                // edit an existing module, get it from manager
224                o = OpenCms.getModuleManager().getModule(m_paramModule);
225            } else {
226                // create a new module
227                o = null;
228            }
229        } else {
230            // this is not the initial call, get module from session
231            o = getDialogObject();
232        }
233
234        if (!(o instanceof CmsModule)) {
235            // create a new module
236            m_module = new CmsModule();
237
238        } else {
239            // reuse module stored in session
240            m_module = (CmsModule)((CmsModule)o).clone();
241        }
242    }
243
244    /**
245     * @see org.opencms.workplace.CmsWorkplace#initWorkplaceRequestValues(org.opencms.workplace.CmsWorkplaceSettings, javax.servlet.http.HttpServletRequest)
246     */
247    @Override
248    protected void initWorkplaceRequestValues(CmsWorkplaceSettings settings, HttpServletRequest request) {
249
250        // set the dialog type
251        setParamDialogtype(DIALOG_TYPE);
252
253        super.initWorkplaceRequestValues(settings, request);
254
255        // save the current state of the module (may be changed because of the widget values)
256        setDialogObject(m_module);
257    }
258
259    /**
260     * @see org.opencms.workplace.CmsWidgetDialog#validateParamaters()
261     */
262    @Override
263    protected void validateParamaters() throws Exception {
264
265        String moduleName = getParamModule();
266        // check module
267        if (!isNewModule()) {
268            CmsModule module = OpenCms.getModuleManager().getModule(moduleName);
269            if (module == null) {
270                throw new Exception();
271            }
272        }
273    }
274
275    /**
276     * Creates all module folders that are selected in the input form.<p>
277     *
278     * @param module the module
279     *
280     * @return the updated module
281     *
282     * @throws CmsException if somehting goes wrong
283     */
284    private CmsModule createModuleFolders(CmsModule module) throws CmsException {
285
286        String modulePath = CmsWorkplace.VFS_PATH_MODULES + module.getName() + "/";
287        List<CmsExportPoint> exportPoints = module.getExportPoints();
288        List<String> resources = module.getResources();
289
290        // set the createModuleFolder flag if any other flag is set
291        if (module.isCreateClassesFolder()
292            || module.isCreateElementsFolder()
293            || module.isCreateLibFolder()
294            || module.isCreateResourcesFolder()
295            || module.isCreateSchemasFolder()
296            || module.isCreateTemplateFolder()
297            || module.isCreateFormattersFolder()) {
298            module.setCreateModuleFolder(true);
299        }
300
301        // check if we have to create the module folder
302        int folderId = CmsResourceTypeFolder.getStaticTypeId();
303        if (module.isCreateModuleFolder()) {
304            getCms().createResource(modulePath, folderId);
305            // add the module folder to the resource list
306            resources.add(modulePath);
307            module.setResources(resources);
308        }
309
310        // check if we have to create the template folder
311        if (module.isCreateTemplateFolder()) {
312            String path = modulePath + PATH_TEMPLATES;
313            getCms().createResource(path, folderId);
314        }
315
316        // check if we have to create the elements folder
317        if (module.isCreateElementsFolder()) {
318            String path = modulePath + PATH_ELEMENTS;
319            getCms().createResource(path, folderId);
320        }
321
322        if (module.isCreateFormattersFolder()) {
323            String path = modulePath + PATH_FORMATTERS;
324            getCms().createResource(path, folderId);
325        }
326
327        // check if we have to create the schemas folder
328        if (module.isCreateSchemasFolder()) {
329            String path = modulePath + PATH_SCHEMAS;
330            getCms().createResource(path, folderId);
331        }
332
333        // check if we have to create the resources folder
334        if (module.isCreateResourcesFolder()) {
335            String path = modulePath + PATH_RESOURCES;
336            getCms().createResource(path, folderId);
337        }
338
339        // check if we have to create the lib folder
340        if (module.isCreateLibFolder()) {
341            String path = modulePath + PATH_LIB;
342            getCms().createResource(path, folderId);
343            CmsExportPoint exp = new CmsExportPoint(path, "WEB-INF/lib/");
344            exportPoints.add(exp);
345            module.setExportPoints(exportPoints);
346        }
347
348        // check if we have to create the classes folder
349        if (module.isCreateClassesFolder()) {
350            String path = modulePath + PATH_CLASSES;
351            getCms().createResource(path, folderId);
352            CmsExportPoint exp = new CmsExportPoint(path, "WEB-INF/classes/");
353            exportPoints.add(exp);
354            module.setExportPoints(exportPoints);
355
356            // now create all subfolders for the package structure
357            StringTokenizer tok = new StringTokenizer(m_module.getName(), ".");
358            while (tok.hasMoreTokens()) {
359                String folder = tok.nextToken();
360                path += folder + "/";
361                getCms().createResource(path, folderId);
362            }
363        }
364        return module;
365    }
366
367    /**
368     * Checks if the new module dialog has to be displayed.<p>
369     *
370     * @return <code>true</code> if the new module dialog has to be displayed
371     */
372    private boolean isNewModule() {
373
374        return getCurrentToolPath().equals("/modules/modules_new");
375    }
376}