001/*
002 * This library is part of OpenCms -
003 * the Open Source Content Management System
004 *
005 * Copyright (c) Alkacon Software GmbH (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, 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.module;
029
030import org.opencms.configuration.CmsVfsConfiguration;
031import org.opencms.configuration.CmsWorkplaceConfiguration;
032import org.opencms.configuration.I_CmsConfigurationParameterHandler;
033import org.opencms.configuration.I_CmsXmlConfiguration;
034import org.opencms.db.CmsExportPoint;
035import org.opencms.file.types.I_CmsResourceType;
036import org.opencms.main.CmsLog;
037import org.opencms.module.CmsModule.ExportMode;
038import org.opencms.util.CmsDateUtil;
039import org.opencms.util.CmsStringUtil;
040import org.opencms.workplace.CmsWorkplace;
041import org.opencms.workplace.explorer.CmsExplorerTypeSettings;
042
043import java.text.ParseException;
044import java.util.ArrayList;
045import java.util.Collections;
046import java.util.HashMap;
047import java.util.Iterator;
048import java.util.List;
049import java.util.Map;
050import java.util.SortedMap;
051
052import org.apache.commons.digester.Digester;
053import org.apache.commons.logging.Log;
054
055import org.dom4j.Document;
056import org.dom4j.DocumentHelper;
057import org.dom4j.Element;
058
059/**
060 * Adds the XML handler rules for import and export of a single module.<p>
061 *
062 * @since 6.0.0
063 */
064public class CmsModuleXmlHandler {
065
066    /** The "name" attribute. */
067    public static final String A_NAME = "name";
068
069    /** The "version" attribute. */
070    public static final String A_VERSION = "version";
071
072    /** The node name for the authoremail node. */
073    public static final String N_AUTHOREMAIL = "authoremail";
074
075    /** The node name for the authorname node. */
076    public static final String N_AUTHORNAME = "authorname";
077
078    /** The node name for the class node. */
079    public static final String N_CLASS = "class";
080
081    /** The node name for the datecreated node. */
082    public static final String N_DATECREATED = "datecreated";
083
084    /** The node name for the date installed node. */
085    public static final String N_DATEINSTALLED = "dateinstalled";
086
087    /** The node name for the dependencies node. */
088    public static final String N_DEPENDENCIES = "dependencies";
089
090    /** The node name for the dependency node. */
091    public static final String N_DEPENDENCY = "dependency";
092
093    /** The node name for the description node. */
094    public static final String N_DESCRIPTION = "description";
095
096    /** The node name for the group node. */
097    public static final String N_GROUP = "group";
098
099    /** Node for the import script. */
100    public static final String N_IMPORT_SCRIPT = "import-script";
101
102    /** The node name for a module. */
103    public static final String N_MODULE = "module";
104
105    /** The node name for the name node. */
106    public static final String N_NAME = "name";
107
108    /** The node name for the nicename node. */
109    public static final String N_NICENAME = "nicename";
110
111    /** The "param" node name for generic parameters. */
112    public static final String N_PARAM = "param";
113
114    /** The node name for the parameters node. */
115    public static final String N_PARAMETERS = "parameters";
116
117    /** The node name for the resources node. */
118    public static final String N_RESOURCES = "resources";
119
120    /** The node name for the resources node. */
121    public static final String N_EXCLUDERESOURCES = "excluderesources";
122
123    /** The node name for the user installed node. */
124    public static final String N_USERINSTALLED = "userinstalled";
125
126    /** The node name for the version node. */
127    public static final String N_VERSION = "version";
128
129    /** The log object for this class. */
130    private static final Log LOG = CmsLog.getLog(CmsModuleXmlHandler.class);
131
132    /** The node name for the import site. */
133    private static final String N_IMPORT_SITE = "import-site";
134
135    /** The node name for the import site. */
136    private static final String N_EXPORT_MODE = "export-mode";
137
138    /** The list of dependencies for a module. */
139    private List<CmsModuleDependency> m_dependencies;
140
141    /** The explorer type settings. */
142    private List<CmsExplorerTypeSettings> m_explorerTypeSettings;
143
144    /** The list of export points for a module. */
145    private List<CmsExportPoint> m_exportPoints;
146
147    /** The generated module. */
148    private CmsModule m_module;
149
150    /** Indicates if the module was an old (5.0.x) style module. */
151    private boolean m_oldModule;
152
153    /** The module parameters. */
154    private Map<String, String> m_parameters;
155
156    /** The list of resources for a module. */
157    private List<String> m_resources;
158
159    /** The list of resources excluded for a module. */
160    private List<String> m_excluderesources;
161
162    /** The list of additional resource types. */
163    private List<I_CmsResourceType> m_resourceTypes;
164
165    /**
166     * Public constructor, will be called by digester during import.<p>
167     */
168    public CmsModuleXmlHandler() {
169
170        m_exportPoints = new ArrayList<CmsExportPoint>();
171        m_dependencies = new ArrayList<CmsModuleDependency>();
172        m_resources = new ArrayList<String>();
173        m_excluderesources = new ArrayList<String>();
174        m_parameters = new HashMap<String, String>();
175        m_resourceTypes = new ArrayList<I_CmsResourceType>();
176        m_explorerTypeSettings = new ArrayList<CmsExplorerTypeSettings>();
177    }
178
179    /**
180     * Adds the XML digester rules for a single module.<p>
181     *
182     * @param digester the digester to add the rules to
183     */
184    public static void addXmlDigesterRules(Digester digester) {
185
186        // add class generation rule
187        digester.addObjectCreate("*/" + N_MODULE, CmsModuleXmlHandler.class);
188        digester.addSetNext("*/" + N_MODULE, "setModule");
189
190        // add rules for base module information
191
192        // NOTE: If you change the order of parameters here or add new ones, you may
193        // also need to change the corresponding parameter indexes in the method addXmlDigesterRulesForVersion5Modules.
194
195        digester.addCallMethod("*/" + N_MODULE, "createdModule", 14);
196        digester.addCallParam("*/" + N_MODULE + "/" + N_NAME, 0);
197        digester.addCallParam("*/" + N_MODULE + "/" + N_NICENAME, 1);
198        digester.addCallParam("*/" + N_MODULE + "/" + N_GROUP, 2);
199        digester.addCallParam("*/" + N_MODULE + "/" + N_CLASS, 3);
200        digester.addCallParam("*/" + N_MODULE + "/" + N_IMPORT_SCRIPT, 4);
201        digester.addCallParam("*/" + N_MODULE + "/" + N_IMPORT_SITE, 5);
202        digester.addCallParam("*/" + N_MODULE + "/" + N_EXPORT_MODE, 6, I_CmsXmlConfiguration.A_NAME);
203        digester.addCallParam("*/" + N_MODULE + "/" + N_DESCRIPTION, 7);
204        digester.addCallParam("*/" + N_MODULE + "/" + N_VERSION, 8);
205        digester.addCallParam("*/" + N_MODULE + "/" + N_AUTHORNAME, 9);
206        digester.addCallParam("*/" + N_MODULE + "/" + N_AUTHOREMAIL, 10);
207        digester.addCallParam("*/" + N_MODULE + "/" + N_DATECREATED, 11);
208        digester.addCallParam("*/" + N_MODULE + "/" + N_USERINSTALLED, 12);
209        digester.addCallParam("*/" + N_MODULE + "/" + N_DATEINSTALLED, 13);
210
211        // add rules for module dependencies
212        digester.addCallMethod("*/" + N_MODULE + "/" + N_DEPENDENCIES + "/" + N_DEPENDENCY, "addDependency", 2);
213        digester.addCallParam(
214            "*/" + N_MODULE + "/" + N_DEPENDENCIES + "/" + N_DEPENDENCY,
215            0,
216            I_CmsXmlConfiguration.A_NAME);
217        digester.addCallParam("*/" + N_MODULE + "/" + N_DEPENDENCIES + "/" + N_DEPENDENCY, 1, A_VERSION);
218
219        // add rules for the module export points
220        digester.addCallMethod(
221            "*/" + N_MODULE + "/" + I_CmsXmlConfiguration.N_EXPORTPOINTS + "/" + I_CmsXmlConfiguration.N_EXPORTPOINT,
222            "addExportPoint",
223            2);
224        digester.addCallParam(
225            "*/" + N_MODULE + "/" + I_CmsXmlConfiguration.N_EXPORTPOINTS + "/" + I_CmsXmlConfiguration.N_EXPORTPOINT,
226            0,
227            I_CmsXmlConfiguration.A_URI);
228        digester.addCallParam(
229            "*/" + N_MODULE + "/" + I_CmsXmlConfiguration.N_EXPORTPOINTS + "/" + I_CmsXmlConfiguration.N_EXPORTPOINT,
230            1,
231            I_CmsXmlConfiguration.A_DESTINATION);
232
233        // add rules for the module resources
234        digester.addCallMethod(
235            "*/" + N_MODULE + "/" + N_RESOURCES + "/" + I_CmsXmlConfiguration.N_RESOURCE,
236            "addResource",
237            1);
238        digester.addCallParam(
239            "*/" + N_MODULE + "/" + N_RESOURCES + "/" + I_CmsXmlConfiguration.N_RESOURCE,
240            0,
241            I_CmsXmlConfiguration.A_URI);
242
243        // add rules for the module exclude resources
244        digester.addCallMethod(
245            "*/" + N_MODULE + "/" + N_EXCLUDERESOURCES + "/" + I_CmsXmlConfiguration.N_RESOURCE,
246            "addExcludeResource",
247            1);
248        digester.addCallParam(
249            "*/" + N_MODULE + "/" + N_EXCLUDERESOURCES + "/" + I_CmsXmlConfiguration.N_RESOURCE,
250            0,
251            I_CmsXmlConfiguration.A_URI);
252
253        // add rules for the module parameters
254        digester.addCallMethod(
255            "*/" + N_MODULE + "/" + N_PARAMETERS + "/" + I_CmsXmlConfiguration.N_PARAM,
256            "addParameter",
257            2);
258        digester.addCallParam(
259            "*/" + N_MODULE + "/" + N_PARAMETERS + "/" + I_CmsXmlConfiguration.N_PARAM,
260            0,
261            I_CmsXmlConfiguration.A_NAME);
262        digester.addCallParam("*/" + N_MODULE + "/" + N_PARAMETERS + "/" + I_CmsXmlConfiguration.N_PARAM, 1);
263
264        // generic <param> parameter rules
265        digester.addCallMethod(
266            "*/" + I_CmsXmlConfiguration.N_PARAM,
267            I_CmsConfigurationParameterHandler.ADD_PARAMETER_METHOD,
268            2);
269        digester.addCallParam("*/" + I_CmsXmlConfiguration.N_PARAM, 0, I_CmsXmlConfiguration.A_NAME);
270        digester.addCallParam("*/" + I_CmsXmlConfiguration.N_PARAM, 1);
271
272        // add resource type rules from VFS
273        CmsVfsConfiguration.addResourceTypeXmlRules(digester);
274
275        // add explorer type rules from workplace
276        CmsWorkplaceConfiguration.addExplorerTypeXmlRules(digester);
277
278        // finally add all rules for backward compatibility with OpenCms 5.0
279        addXmlDigesterRulesForVersion5Modules(digester);
280    }
281
282    /**
283     * Generates a detached XML element for a module.<p>
284     *
285     * @param module the module to generate the XML element for
286     *
287     * @return the detached XML element for the module
288     */
289    public static Element generateXml(CmsModule module) {
290
291        Document doc = DocumentHelper.createDocument();
292
293        Element moduleElement = doc.addElement(N_MODULE);
294
295        moduleElement.addElement(N_NAME).setText(module.getName());
296        if (!module.getName().equals(module.getNiceName())) {
297            moduleElement.addElement(N_NICENAME).addCDATA(module.getNiceName());
298        } else {
299            moduleElement.addElement(N_NICENAME);
300        }
301        if (CmsStringUtil.isNotEmpty(module.getGroup())) {
302            moduleElement.addElement(N_GROUP).setText(module.getGroup());
303        }
304        if (CmsStringUtil.isNotEmpty(module.getActionClass())) {
305            moduleElement.addElement(N_CLASS).setText(module.getActionClass());
306        } else {
307            moduleElement.addElement(N_CLASS);
308        }
309
310        String importScript = module.getImportScript();
311        if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(importScript)) {
312            moduleElement.addElement(N_IMPORT_SCRIPT).setText(importScript);
313        }
314
315        String importSite = module.getImportSite();
316        if (!CmsStringUtil.isEmptyOrWhitespaceOnly(importSite)) {
317            moduleElement.addElement(N_IMPORT_SITE).setText(importSite);
318        }
319
320        moduleElement.addElement(N_EXPORT_MODE).addAttribute(A_NAME, module.getExportMode().toString());
321
322        if (CmsStringUtil.isNotEmpty(module.getDescription())) {
323            moduleElement.addElement(N_DESCRIPTION).addCDATA(module.getDescription());
324        } else {
325            moduleElement.addElement(N_DESCRIPTION);
326        }
327        moduleElement.addElement(N_VERSION).setText(module.getVersion().toString());
328        if (CmsStringUtil.isNotEmpty(module.getAuthorName())) {
329            moduleElement.addElement(N_AUTHORNAME).addCDATA(module.getAuthorName());
330        } else {
331            moduleElement.addElement(N_AUTHORNAME);
332        }
333        if (CmsStringUtil.isNotEmpty(module.getAuthorEmail())) {
334            moduleElement.addElement(N_AUTHOREMAIL).addCDATA(module.getAuthorEmail());
335        } else {
336            moduleElement.addElement(N_AUTHOREMAIL);
337        }
338        if (module.getDateCreated() != CmsModule.DEFAULT_DATE) {
339            moduleElement.addElement(N_DATECREATED).setText(CmsDateUtil.getHeaderDate(module.getDateCreated()));
340        } else {
341            moduleElement.addElement(N_DATECREATED);
342        }
343
344        if (!module.isReducedExportMode() && CmsStringUtil.isNotEmpty(module.getUserInstalled())) {
345            moduleElement.addElement(N_USERINSTALLED).setText(module.getUserInstalled());
346        } else {
347            moduleElement.addElement(N_USERINSTALLED);
348        }
349        if (!module.isReducedExportMode() && (module.getDateInstalled() != CmsModule.DEFAULT_DATE)) {
350            moduleElement.addElement(N_DATEINSTALLED).setText(CmsDateUtil.getHeaderDate(module.getDateInstalled()));
351        } else {
352            moduleElement.addElement(N_DATEINSTALLED);
353        }
354        Element dependenciesElement = moduleElement.addElement(N_DEPENDENCIES);
355        for (int i = 0; i < module.getDependencies().size(); i++) {
356            CmsModuleDependency dependency = module.getDependencies().get(i);
357            dependenciesElement.addElement(N_DEPENDENCY).addAttribute(
358                I_CmsXmlConfiguration.A_NAME,
359                dependency.getName()).addAttribute(A_VERSION, dependency.getVersion().toString());
360        }
361        Element exportpointsElement = moduleElement.addElement(I_CmsXmlConfiguration.N_EXPORTPOINTS);
362        for (int i = 0; i < module.getExportPoints().size(); i++) {
363            CmsExportPoint point = module.getExportPoints().get(i);
364            exportpointsElement.addElement(I_CmsXmlConfiguration.N_EXPORTPOINT).addAttribute(
365                I_CmsXmlConfiguration.A_URI,
366                point.getUri()).addAttribute(I_CmsXmlConfiguration.A_DESTINATION, point.getConfiguredDestination());
367        }
368        Element resourcesElement = moduleElement.addElement(N_RESOURCES);
369        for (int i = 0; i < module.getResources().size(); i++) {
370            String resource = module.getResources().get(i);
371            resourcesElement.addElement(I_CmsXmlConfiguration.N_RESOURCE).addAttribute(
372                I_CmsXmlConfiguration.A_URI,
373                resource);
374        }
375        Element excludeResourcesElement = moduleElement.addElement(N_EXCLUDERESOURCES);
376        for (String resource : module.getExcludeResources()) {
377            excludeResourcesElement.addElement(I_CmsXmlConfiguration.N_RESOURCE).addAttribute(
378                I_CmsXmlConfiguration.A_URI,
379                resource);
380        }
381        Element parametersElement = moduleElement.addElement(N_PARAMETERS);
382        SortedMap<String, String> parameters = module.getParameters();
383        if (parameters != null) {
384            List<String> names = new ArrayList<String>(parameters.keySet());
385            Collections.sort(names);
386            for (String name : names) {
387                String value = parameters.get(name).toString();
388                Element paramNode = parametersElement.addElement(I_CmsXmlConfiguration.N_PARAM);
389                paramNode.addAttribute(I_CmsXmlConfiguration.A_NAME, name);
390                paramNode.addText(value);
391            }
392        }
393
394        // add resource types
395        List<I_CmsResourceType> resourceTypes = module.getResourceTypes();
396        if (resourceTypes.size() > 0) {
397            Element resourcetypesElement = moduleElement.addElement(CmsVfsConfiguration.N_RESOURCETYPES);
398            CmsVfsConfiguration.generateResourceTypeXml(resourcetypesElement, resourceTypes, true);
399        }
400
401        List<CmsExplorerTypeSettings> explorerTypes = module.getExplorerTypes();
402        if (explorerTypes.size() > 0) {
403            Element explorerTypesElement = moduleElement.addElement(CmsWorkplaceConfiguration.N_EXPLORERTYPES);
404            CmsWorkplaceConfiguration.generateExplorerTypesXml(explorerTypesElement, explorerTypes, true);
405        }
406
407        // return the modules node
408        moduleElement.detach();
409        return moduleElement;
410    }
411
412    /**
413     * Generates a (hopefully) valid Java class name from an invalid class name.<p>
414     *
415     * All invalid characters are replaced by an underscore "_".
416     * This is for example used to make sure old (5.0) modules can still be imported,
417     * by converting the name to a valid class name.<p>
418     *
419     * @param className the class name to make valid
420     *
421     * @return a valid Java class name from an invalid class name
422     */
423    public static String makeValidJavaClassName(String className) {
424
425        StringBuffer result = new StringBuffer(className.length());
426        int length = className.length();
427        boolean nodot = true;
428        for (int i = 0; i < length; i++) {
429            char ch = className.charAt(i);
430            if (nodot) {
431                if (ch == '.') {
432                    // ignore, remove
433                } else if (Character.isJavaIdentifierStart(ch)) {
434                    nodot = false;
435                    result.append(ch);
436                } else {
437                    result.append('_');
438                }
439            } else {
440                if (ch == '.') {
441                    nodot = true;
442                    result.append(ch);
443                } else if (Character.isJavaIdentifierPart(ch)) {
444                    nodot = false;
445                    result.append(ch);
446                } else {
447                    result.append('_');
448                }
449            }
450        }
451        return result.toString();
452    }
453
454    /**
455     * Adds the digester rules for OpenCms version 5 modules.<p>
456     *
457     * @param digester the digester to add the rules to
458     */
459    private static void addXmlDigesterRulesForVersion5Modules(Digester digester) {
460
461        // mark method
462        digester.addCallMethod("*/" + N_MODULE + "/author", "setOldModule");
463
464        // base module information
465        digester.addCallParam("*/" + N_MODULE + "/author", 9);
466        digester.addCallParam("*/" + N_MODULE + "/email", 10);
467        digester.addCallParam("*/" + N_MODULE + "/creationdate", 11);
468
469        // dependencies
470        digester.addCallParam("*/" + N_MODULE + "/dependencies/dependency/name", 0);
471        digester.addCallParam("*/" + N_MODULE + "/dependencies/dependency/minversion", 1);
472
473        // export points
474        digester.addCallMethod("*/" + N_MODULE + "/exportpoint", "addExportPoint", 2);
475        digester.addCallParam("*/" + N_MODULE + "/exportpoint/source", 0);
476        digester.addCallParam("*/" + N_MODULE + "/exportpoint/destination", 1);
477
478        // parameters
479        digester.addCallMethod("*/" + N_MODULE + "/parameters/para", "addParameter", 2);
480        digester.addCallParam("*/" + N_MODULE + "/parameters/para/name", 0);
481        digester.addCallParam("*/" + N_MODULE + "/parameters/para/value", 1);
482    }
483
484    /**
485     * Adds a module dependency to the current module.<p>
486     *
487     * @param name the module name of the dependency
488     * @param version the module version of the dependency
489     */
490    public void addDependency(String name, String version) {
491
492        CmsModuleVersion moduleVersion = new CmsModuleVersion(version);
493
494        CmsModuleDependency dependency = new CmsModuleDependency(name, moduleVersion);
495        m_dependencies.add(dependency);
496
497        if (LOG.isDebugEnabled()) {
498            LOG.debug(Messages.get().getBundle().key(Messages.LOG_ADD_MOD_DEPENDENCY_2, name, version));
499        }
500    }
501
502    /**
503     * Adds a resource to the list module resources.<p>
504     *
505     * @param resource a resources uri in the OpenCms VFS
506     */
507    public void addExcludeResource(String resource) {
508
509        if (LOG.isDebugEnabled()) {
510            LOG.debug(Messages.get().getBundle().key(Messages.LOG_ADD_MOD_EXCLUDERESOURCE_1, resource));
511        }
512        m_excluderesources.add(resource);
513    }
514
515    /**
516     * Adds an explorer type setting object to the list of type settings.<p>
517     *
518     * Adds the type setting as well to a map with the resource type name as key.
519     *
520     * @param settings the explorer type settings
521     */
522    public void addExplorerTypeSetting(CmsExplorerTypeSettings settings) {
523
524        settings.setAddititionalModuleExplorerType(true);
525        m_explorerTypeSettings.add(settings);
526    }
527
528    /**
529     * Adds an export point to the module configuration.<p>
530     *
531     * @param uri the export point uri
532     * @param destination the export point destination
533     */
534    public void addExportPoint(String uri, String destination) {
535
536        CmsExportPoint point = new CmsExportPoint(uri, destination);
537        m_exportPoints.add(point);
538        if (CmsLog.INIT.isInfoEnabled()) {
539            CmsLog.INIT.info(
540                Messages.get().getBundle().key(
541                    Messages.INIT_ADD_EXPORT_POINT_2,
542                    point.getUri(),
543                    point.getConfiguredDestination()));
544        }
545    }
546
547    /**
548     * Adds a module parameter to the module configuration.<p>
549     *
550     * @param key the parameter key
551     * @param value the parameter value
552     */
553    public void addParameter(String key, String value) {
554
555        if (CmsStringUtil.isNotEmpty(key)) {
556            key = key.trim();
557        }
558        if (CmsStringUtil.isNotEmpty(value)) {
559            value = value.trim();
560        }
561        m_parameters.put(key, value);
562        if (LOG.isDebugEnabled()) {
563            LOG.debug(Messages.get().getBundle().key(Messages.LOG_ADD_MOD_PARAM_KEY_2, key, value));
564        }
565    }
566
567    /**
568     * Adds a resource to the list module resources.<p>
569     *
570     * @param resource a resources uri in the OpenCms VFS
571     */
572    public void addResource(String resource) {
573
574        if (LOG.isDebugEnabled()) {
575            LOG.debug(Messages.get().getBundle().key(Messages.LOG_ADD_MOD_RESOURCE_1, resource));
576        }
577        m_resources.add(resource);
578    }
579
580    /**
581     * Adds a new resource type to the internal list of loaded resource types.<p>
582     *
583     * @param resourceType the resource type to add
584     *
585     * @see I_CmsResourceType#ADD_RESOURCE_TYPE_METHOD
586     */
587    public void addResourceType(I_CmsResourceType resourceType) {
588
589        resourceType.setAdditionalModuleResourceType(true);
590        m_resourceTypes.add(resourceType);
591    }
592
593    /**
594     * Created a new module from the provided parameters.<p>
595     *
596     * @param name the name of this module, usually looks like a java package name
597     * @param niceName the "nice" display name of this module
598     * @param group the group of the module
599     * @param actionClass the (optional) module action class name
600     * @param importScript the import script
601     * @param importSite the import site root
602     * @param exportModeName the export mode name
603     * @param description the description of this module
604     * @param version the version of this module
605     * @param authorName the name of the author of this module
606     * @param authorEmail the email of the module author
607     * @param dateCreated the date this module was created by the author
608     * @param userInstalled the name of the user who uploaded this module
609     * @param dateInstalled the date this module was uploaded
610     */
611    public void createdModule(
612        String name,
613        String niceName,
614        String group,
615        String actionClass,
616        String importScript,
617        String importSite,
618        String exportModeName,
619        String description,
620        String version,
621        String authorName,
622        String authorEmail,
623        String dateCreated,
624        String userInstalled,
625        String dateInstalled) {
626
627        String moduleName;
628
629        if (!CmsStringUtil.isValidJavaClassName(name)) {
630            // ensure backward compatibility with old (5.0) module names
631            LOG.error(Messages.get().getBundle().key(Messages.LOG_INVALID_MOD_NAME_IMPORTED_1, name));
632            moduleName = makeValidJavaClassName(name);
633            LOG.error(Messages.get().getBundle().key(Messages.LOG_CORRECTED_MOD_NAME_1, moduleName));
634        } else {
635            moduleName = name;
636        }
637
638        // parse the module version
639        CmsModuleVersion moduleVersion = new CmsModuleVersion(version);
640
641        // parse date created
642        long moduleDateCreated = CmsModule.DEFAULT_DATE;
643        if (dateCreated != null) {
644            try {
645                moduleDateCreated = CmsDateUtil.parseHeaderDate(dateCreated);
646            } catch (ParseException e) {
647                // noop
648            }
649        }
650
651        // parse date installed
652        long moduleDateInstalled = CmsModule.DEFAULT_DATE;
653        if (dateInstalled != null) {
654            try {
655                moduleDateInstalled = CmsDateUtil.parseHeaderDate(dateInstalled);
656            } catch (ParseException e1) {
657                // noop
658            }
659        }
660
661        if (m_oldModule) {
662            // make sure module path is added to resources for "old" (5.0.x) modules
663            String modulePath = CmsWorkplace.VFS_PATH_MODULES + name + "/";
664            m_resources.add(modulePath);
665        }
666
667        ExportMode exportMode = ExportMode.DEFAULT;
668        try {
669            if (!CmsStringUtil.isEmptyOrWhitespaceOnly(exportModeName)) {
670                exportMode = ExportMode.valueOf(exportModeName.toUpperCase());
671            }
672        } catch (@SuppressWarnings("unused") IllegalArgumentException e) {
673            // TODO: log entry? But shouldn't happen anyway because of DTD restrictions
674            //stay with default export mode
675        }
676
677        // now create the module
678        m_module = new CmsModule(
679            moduleName,
680            niceName,
681            group,
682            actionClass,
683            importScript,
684            importSite,
685            exportMode,
686            description,
687            moduleVersion,
688            authorName,
689            authorEmail,
690            moduleDateCreated,
691            userInstalled,
692            moduleDateInstalled,
693            m_dependencies,
694            m_exportPoints,
695            m_resources,
696            m_excluderesources,
697            m_parameters);
698
699        // store module name in the additional resource types
700        List<I_CmsResourceType> moduleResourceTypes = new ArrayList<I_CmsResourceType>(m_resourceTypes.size());
701        for (Iterator<I_CmsResourceType> i = m_resourceTypes.iterator(); i.hasNext();) {
702            I_CmsResourceType resType = i.next();
703            resType.setModuleName(moduleName);
704            moduleResourceTypes.add(resType);
705        }
706        // set the additional resource types;
707        m_module.setResourceTypes(moduleResourceTypes);
708
709        // set the additional explorer types
710        m_module.setExplorerTypes(m_explorerTypeSettings);
711    }
712
713    /**
714     * Returns the generated module.<p>
715     *
716     * @return the generated module
717     */
718    public CmsModule getModule() {
719
720        return m_module;
721    }
722
723    /**
724     * Sets the current imported module to an old (5.0.x) style module.
725     */
726    public void setOldModule() {
727
728        m_oldModule = true;
729        if (LOG.isDebugEnabled()) {
730            LOG.debug(Messages.get().getBundle().key(Messages.LOG_OLD_MODULE_IMPORTED_0));
731        }
732    }
733}