KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > opencms > module > CmsModuleManager


1 /*
2  * File : $Source: /usr/local/cvs/opencms/src/org/opencms/module/CmsModuleManager.java,v $
3  * Date : $Date: 2006/03/27 14:53:03 $
4  * Version: $Revision: 1.35 $
5  *
6  * This library is part of OpenCms -
7  * the Open Source Content Mananagement System
8  *
9  * Copyright (c) 2005 Alkacon Software GmbH (http://www.alkacon.com)
10  *
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public
13  * License as published by the Free Software Foundation; either
14  * version 2.1 of the License, or (at your option) any later version.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  * Lesser General Public License for more details.
20  *
21  * For further information about Alkacon Software GmbH, please see the
22  * company website: http://www.alkacon.com
23  *
24  * For further information about OpenCms, please see the
25  * project website: http://www.opencms.org
26  *
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30  */

31
32 package org.opencms.module;
33
34 import org.opencms.configuration.CmsConfigurationException;
35 import org.opencms.configuration.CmsConfigurationManager;
36 import org.opencms.configuration.CmsModuleConfiguration;
37 import org.opencms.db.CmsExportPoint;
38 import org.opencms.file.CmsObject;
39 import org.opencms.file.CmsProject;
40 import org.opencms.file.CmsResource;
41 import org.opencms.importexport.CmsImportExportManager;
42 import org.opencms.main.CmsException;
43 import org.opencms.main.CmsIllegalArgumentException;
44 import org.opencms.main.CmsIllegalStateException;
45 import org.opencms.main.CmsLog;
46 import org.opencms.main.CmsRuntimeException;
47 import org.opencms.main.OpenCms;
48 import org.opencms.report.I_CmsReport;
49 import org.opencms.security.CmsRole;
50 import org.opencms.security.CmsRoleViolationException;
51 import org.opencms.security.CmsSecurityException;
52
53 import java.io.File JavaDoc;
54 import java.util.ArrayList JavaDoc;
55 import java.util.Collections JavaDoc;
56 import java.util.HashMap JavaDoc;
57 import java.util.HashSet JavaDoc;
58 import java.util.Hashtable JavaDoc;
59 import java.util.Iterator JavaDoc;
60 import java.util.List JavaDoc;
61 import java.util.Map JavaDoc;
62 import java.util.Set JavaDoc;
63
64 import org.apache.commons.logging.Log;
65
66 /**
67  * Manages the modules of an OpenCms installation.<p>
68  *
69  * @author Alexander Kandzior
70  * @author Michael Moossen
71  *
72  * @version $Revision: 1.35 $
73  *
74  * @since 6.0.0
75  */

76 public class CmsModuleManager {
77
78     /** Indicates dependency check for module deletion. */
79     public static final int DEPENDENCY_MODE_DELETE = 0;
80
81     /** Indicates dependency check for module import. */
82     public static final int DEPENDENCY_MODE_IMPORT = 1;
83
84     /** The log object for this class. */
85     private static final Log LOG = CmsLog.getLog(CmsModuleManager.class);
86
87     /** The list of module export points. */
88     private Set JavaDoc m_moduleExportPoints;
89
90     /** The map of configured modules. */
91     private Map JavaDoc m_modules;
92
93     /**
94      * Basic constructor.<p>
95      *
96      * @param configuredModules the list of configured modules
97      */

98     public CmsModuleManager(List JavaDoc configuredModules) {
99
100         if (CmsLog.INIT.isInfoEnabled()) {
101             CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_MOD_MANAGER_CREATED_0));
102         }
103
104         m_modules = new Hashtable JavaDoc();
105         for (int i = 0; i < configuredModules.size(); i++) {
106             CmsModule module = (CmsModule)configuredModules.get(i);
107             m_modules.put(module.getName(), module);
108             if (CmsLog.INIT.isInfoEnabled()) {
109                 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_MOD_CONFIGURED_1, module.getName()));
110             }
111         }
112
113         if (CmsLog.INIT.isInfoEnabled()) {
114             CmsLog.INIT.info(Messages.get().getBundle().key(
115                 Messages.INIT_NUM_MODS_CONFIGURED_1,
116                 new Integer JavaDoc(m_modules.size())));
117         }
118         m_moduleExportPoints = Collections.EMPTY_SET;
119     }
120
121     /**
122      * Returns a map of dependencies.<p>
123      *
124      * The module dependencies are get from the installed modules or
125      * from the module manifest.xml files found in the given FRS path.<p>
126      *
127      * Two types of dependency lists can be generated:<br>
128      * <ul>
129      * <li>Forward dependency lists: a list of modules that depends on a module</li>
130      * <li>Backward dependency lists: a list of modules that a module depends on</li>
131      * </ul>
132      *
133      * @param rfsAbsPath a RFS absolute path to search for modules, or <code>null</code> to use the installed modules
134      * @param mode if <code>true</code> a list of forward dependency is build, is not a list of backward dependency
135      *
136      * @return a Map of module names as keys and a list of dependency names as values
137      *
138      * @throws CmsConfigurationException if something goes wrong
139      */

140     public static Map JavaDoc buildDepsForAllModules(String JavaDoc rfsAbsPath, boolean mode) throws CmsConfigurationException {
141
142         Map JavaDoc ret = new HashMap JavaDoc();
143         List JavaDoc modules;
144         if (rfsAbsPath == null) {
145             modules = OpenCms.getModuleManager().getAllInstalledModules();
146         } else {
147             modules = new ArrayList JavaDoc(getAllModulesFromPath(rfsAbsPath).keySet());
148         }
149         Iterator JavaDoc itMods = modules.iterator();
150         while (itMods.hasNext()) {
151             CmsModule module = (CmsModule)itMods.next();
152
153             // if module a depends on module b, and module c depends also on module b:
154
// build a map with a list containing "a" and "c" keyed by "b" to get a
155
// list of modules depending on module "b"...
156
Iterator JavaDoc itDeps = module.getDependencies().iterator();
157             while (itDeps.hasNext()) {
158                 CmsModuleDependency dependency = (CmsModuleDependency)itDeps.next();
159                 // module dependency package name
160
String JavaDoc moduleDependencyName = dependency.getName();
161
162                 if (mode) {
163                     // get the list of dependend modules
164
List JavaDoc moduleDependencies = (List JavaDoc)ret.get(moduleDependencyName);
165                     if (moduleDependencies == null) {
166                         // build a new list if "b" has no dependend modules yet
167
moduleDependencies = new ArrayList JavaDoc();
168                         ret.put(moduleDependencyName, moduleDependencies);
169                     }
170                     // add "a" as a module depending on "b"
171
moduleDependencies.add(module.getName());
172                 } else {
173                     List JavaDoc moduleDependencies = (List JavaDoc)ret.get(module.getName());
174                     if (moduleDependencies == null) {
175                         moduleDependencies = new ArrayList JavaDoc();
176                         ret.put(module.getName(), moduleDependencies);
177                     }
178                     moduleDependencies.add(dependency.getName());
179                 }
180             }
181         }
182         itMods = modules.iterator();
183         while (itMods.hasNext()) {
184             CmsModule module = (CmsModule)itMods.next();
185             if (ret.get(module.getName()) == null) {
186                 ret.put(module.getName(), new ArrayList JavaDoc());
187             }
188         }
189         return ret;
190     }
191
192     /**
193      * Returns a map of dependencies between the given modules.<p>
194      *
195      * The module dependencies are get from the installed modules or
196      * from the module manifest.xml files found in the given FRS path.<p>
197      *
198      * Two types of dependency lists can be generated:<br>
199      * <ul>
200      * <li>Forward dependency lists: a list of modules that depends on a module</li>
201      * <li>Backward dependency lists: a list of modules that a module depends on</li>
202      * </ul>
203      *
204      * @param moduleNames a list of module names
205      * @param rfsAbsPath a RFS absolute path to search for modules, or <code>null</code> to use the installed modules
206      * @param mode if <code>true</code> a list of forward dependency is build, is not a list of backward dependency
207      *
208      * @return a Map of module names as keys and a list of dependency names as values
209      *
210      * @throws CmsConfigurationException if something goes wrong
211      */

212     public static Map JavaDoc buildDepsForModulelist(List JavaDoc moduleNames, String JavaDoc rfsAbsPath, boolean mode)
213     throws CmsConfigurationException {
214
215         Map JavaDoc ret = buildDepsForAllModules(rfsAbsPath, mode);
216         Iterator JavaDoc itMods;
217         if (rfsAbsPath == null) {
218             itMods = OpenCms.getModuleManager().getAllInstalledModules().iterator();
219         } else {
220             itMods = getAllModulesFromPath(rfsAbsPath).keySet().iterator();
221         }
222         while (itMods.hasNext()) {
223             CmsModule module = (CmsModule)itMods.next();
224             if (!moduleNames.contains(module.getName())) {
225                 Iterator JavaDoc itDeps = ret.values().iterator();
226                 while (itDeps.hasNext()) {
227                     List JavaDoc dependencies = (List JavaDoc)itDeps.next();
228                     dependencies.remove(module.getName());
229                 }
230                 ret.remove(module.getName());
231             }
232         }
233         return ret;
234     }
235
236     /**
237      * Returns a map of modules found in the given RFS absolute path.<p>
238      *
239      * @param rfsAbsPath the path to look for module distributions
240      *
241      * @return a map of <code>{@link CmsModule}</code> objects for keys and filename for values
242      *
243      * @throws CmsConfigurationException if something goes wrong
244      */

245     public static Map JavaDoc getAllModulesFromPath(String JavaDoc rfsAbsPath) throws CmsConfigurationException {
246
247         Map JavaDoc modules = new HashMap JavaDoc();
248         if (rfsAbsPath == null) {
249             return modules;
250         }
251         File JavaDoc folder = new File JavaDoc(rfsAbsPath);
252         if (folder.exists()) {
253             // list all child resources in the given folder
254
File JavaDoc[] folderFiles = folder.listFiles();
255             if (folderFiles != null) {
256                 for (int i = 0; i < folderFiles.length; i++) {
257                     File JavaDoc moduleFile = folderFiles[i];
258                     if (moduleFile.isFile() && !(moduleFile.getAbsolutePath().toLowerCase().endsWith(".zip"))) {
259                         // skip non-ZIP files
260
continue;
261                     }
262                     if (moduleFile.isDirectory()) {
263                         File JavaDoc manifest = new File JavaDoc(moduleFile, CmsImportExportManager.EXPORT_MANIFEST);
264                         if (!manifest.exists() || !manifest.canRead()) {
265                             // skip unused directories
266
continue;
267                         }
268                     }
269                     modules.put(
270                         CmsModuleImportExportHandler.readModuleFromImport(moduleFile.getAbsolutePath()),
271                         moduleFile.getName());
272                 }
273             }
274         }
275         return modules;
276     }
277
278     /**
279      * Sorts a given list of module names by dependencies,
280      * so that the resulting list can be imported in that given order,
281      * that means modules without dependencies first.<p>
282      *
283      * The module dependencies are get from the installed modules or
284      * from the module manifest.xml files found in the given FRS path.<p>
285      *
286      * @param moduleNames a list of module names
287      * @param rfsAbsPath a RFS absolute path to search for modules, or <code>null</code> to use the installed modules
288      *
289      * @return a sorted list of module names
290      *
291      * @throws CmsConfigurationException if something goes wrong
292      */

293     public static List JavaDoc topologicalSort(List JavaDoc moduleNames, String JavaDoc rfsAbsPath) throws CmsConfigurationException {
294
295         List JavaDoc modules = new ArrayList JavaDoc(moduleNames);
296         List JavaDoc retList = new ArrayList JavaDoc();
297         Map JavaDoc moduleDependencies = buildDepsForModulelist(moduleNames, rfsAbsPath, true);
298         boolean finished = false;
299         while (!finished) {
300             finished = true;
301             Iterator JavaDoc itMods = modules.iterator();
302             while (itMods.hasNext()) {
303                 String JavaDoc moduleName = (String JavaDoc)itMods.next();
304                 List JavaDoc deps = (List JavaDoc)moduleDependencies.get(moduleName);
305                 if ((deps == null) || deps.isEmpty()) {
306                     retList.add(moduleName);
307                     Iterator JavaDoc itDeps = moduleDependencies.values().iterator();
308                     while (itDeps.hasNext()) {
309                         List JavaDoc dependencies = (List JavaDoc)itDeps.next();
310                         dependencies.remove(moduleName);
311                     }
312                     finished = false;
313                     itMods.remove();
314                 }
315             }
316         }
317         if (!modules.isEmpty()) {
318             throw new CmsIllegalStateException(Messages.get().container(
319                 Messages.ERR_MODULE_DEPENDENCY_CYCLE_1,
320                 modules.toString()));
321         }
322         Collections.reverse(retList);
323         return retList;
324     }
325
326     /**
327      * Adds a new module to the module manager.<p>
328      *
329      * @param cms must be initialized with "Admin" permissions
330      * @param module the module to add
331      *
332      * @throws CmsSecurityException if the required permissions are not available (i.e. no "Admin" CmsObject has been provided)
333      * @throws CmsConfigurationException if a module with this name is already configured
334      */

335     public synchronized void addModule(CmsObject cms, CmsModule module)
336     throws CmsSecurityException, CmsConfigurationException {
337
338         // check the role permissions
339
cms.checkRole(CmsRole.MODULE_MANAGER);
340
341         if (m_modules.containsKey(module.getName())) {
342             // module is currently configured, no create possible
343
throw new CmsConfigurationException(Messages.get().container(
344                 Messages.ERR_MODULE_ALREADY_CONFIGURED_1,
345                 module.getName()));
346
347         }
348
349         if (LOG.isInfoEnabled()) {
350             LOG.info(Messages.get().getBundle().key(Messages.LOG_CREATE_NEW_MOD_1, module.getName()));
351         }
352
353         // initialize the module
354
module.initialize(cms);
355
356         m_modules.put(module.getName(), module);
357
358         try {
359             I_CmsModuleAction moduleAction = module.getActionInstance();
360             // handle module action instance if initialized
361
if (moduleAction != null) {
362                 moduleAction.moduleUpdate(module);
363             }
364         } catch (Throwable JavaDoc t) {
365             LOG.error(Messages.get().getBundle().key(Messages.LOG_MOD_UPDATE_ERR_1, module.getName()), t);
366         }
367
368         // initialize the export points
369
initModuleExportPoints();
370
371         // update the configuration
372
updateModuleConfiguration();
373     }
374
375     /**
376      * Checks if a modules depedencies are fulfilled.<p>
377      *
378      * The possible values for the <code>mode</code> parameter are:<dl>
379      * <dt>{@link #DEPENDENCY_MODE_DELETE}</dt>
380      * <dd>Check for module deleting, i.e. are other modules dependent on the
381      * given module?</dd>
382      * <dt>{@link #DEPENDENCY_MODE_IMPORT}</dt>
383      * <dd>Check for module importing, i.e. are all dependencies required by the given
384      * module available?</dd></dl>
385      *
386      * @param module the module to check the dependencies for
387      * @param mode the dependency check mode
388      * @return a list of dependencies that are not fulfilled, if empty all dependencies are fulfilled
389      */

390     public List JavaDoc checkDependencies(CmsModule module, int mode) {
391
392         List JavaDoc result = new ArrayList JavaDoc();
393
394         if (mode == DEPENDENCY_MODE_DELETE) {
395             // delete mode, check if other modules depend on this module
396
Iterator JavaDoc i = m_modules.values().iterator();
397             while (i.hasNext()) {
398                 CmsModule otherModule = (CmsModule)i.next();
399                 CmsModuleDependency dependency = otherModule.checkDependency(module);
400                 if (dependency != null) {
401                     // dependency found, add to list
402
result.add(new CmsModuleDependency(otherModule.getName(), otherModule.getVersion()));
403                 }
404             }
405
406         } else if (mode == DEPENDENCY_MODE_IMPORT) {
407             // import mode, check if all module dependencies are fulfilled
408
Iterator JavaDoc i = m_modules.values().iterator();
409             // add all dependencies that must be found
410
result.addAll(module.getDependencies());
411             while (i.hasNext() && (result.size() > 0)) {
412                 CmsModule otherModule = (CmsModule)i.next();
413                 CmsModuleDependency dependency = module.checkDependency(otherModule);
414                 if (dependency != null) {
415                     // dependency found, remove from list
416
result.remove(dependency);
417                 }
418             }
419         } else {
420             // invalid mode selected
421
throw new CmsRuntimeException(Messages.get().container(
422                 Messages.ERR_CHECK_DEPENDENCY_INVALID_MODE_1,
423                 new Integer JavaDoc(mode)));
424         }
425
426         return result;
427     }
428
429     /**
430      * Checks the module selection list for consistency, that means
431      * that if a module is selected, all its dependencies are also selected.<p>
432      *
433      * The module dependencies are get from the installed modules or
434      * from the module manifest.xml files found in the given FRS path.<p>
435      *
436      * @param moduleNames a list of module names
437      * @param rfsAbsPath a RFS absolute path to search for modules, or <code>null</code> to use the installed modules
438      * @param forDeletion there are two modes, one for installation of modules, and one for deletion.
439      *
440      * @throws CmsIllegalArgumentException if the module list is not consistent
441      * @throws CmsConfigurationException if something goes wrong
442      */

443     public void checkModuleSelectionList(List JavaDoc moduleNames, String JavaDoc rfsAbsPath, boolean forDeletion)
444     throws CmsIllegalArgumentException, CmsConfigurationException {
445
446         Map JavaDoc moduleDependencies = buildDepsForAllModules(rfsAbsPath, forDeletion);
447         Iterator JavaDoc itMods = moduleNames.iterator();
448         while (itMods.hasNext()) {
449             String JavaDoc moduleName = (String JavaDoc)itMods.next();
450             List JavaDoc dependencies = (List JavaDoc)moduleDependencies.get(moduleName);
451             if (dependencies != null) {
452                 List JavaDoc depModules = new ArrayList JavaDoc(dependencies);
453                 depModules.removeAll(moduleNames);
454                 if (!depModules.isEmpty()) {
455                     throw new CmsIllegalArgumentException(Messages.get().container(
456                         Messages.ERR_MODULE_SELECTION_INCONSISTENT_2,
457                         moduleName,
458                         depModules.toString()));
459                 }
460             }
461         }
462     }
463
464     /**
465      * Deletes a module from the configuration.<p>
466      *
467      * @param cms must be initialized with "Admin" permissions
468      * @param moduleName the name of the module to delete
469      * @param replace indicates if the module is replaced (true) or finally deleted (false)
470      * @param report the report to print progesss messages to
471      *
472      * @throws CmsRoleViolationException if the required module manager role permissions are not available
473      * @throws CmsConfigurationException if a module with this name is not available for deleting
474      */

475     public synchronized void deleteModule(CmsObject cms, String JavaDoc moduleName, boolean replace, I_CmsReport report)
476     throws CmsRoleViolationException, CmsConfigurationException {
477
478         // check for module manager role permissions
479
cms.checkRole(CmsRole.MODULE_MANAGER);
480
481         if (!m_modules.containsKey(moduleName)) {
482             // module is not currently configured, no update possible
483
throw new CmsConfigurationException(Messages.get().container(
484                 Messages.ERR_MODULE_NOT_CONFIGURED_1,
485                 moduleName));
486         }
487
488         if (LOG.isInfoEnabled()) {
489             LOG.info(Messages.get().getBundle().key(Messages.LOG_DEL_MOD_1, moduleName));
490         }
491
492         CmsModule module;
493         boolean removeResourceTypes = false;
494
495         if (!replace) {
496             // module is deleted, not replaced
497
module = (CmsModule)m_modules.get(moduleName);
498             // makr the resource manager to reinitialize if nescessary
499
if (module.getResourceTypes() != Collections.EMPTY_LIST) {
500                 removeResourceTypes = true;
501             }
502             if (module.getExplorerTypes() != Collections.EMPTY_LIST) {
503                 OpenCms.getWorkplaceManager().removeExplorerTypeSettings(module);
504             }
505
506             // perform dependency check
507
List JavaDoc dependencies = checkDependencies(module, DEPENDENCY_MODE_DELETE);
508             if (!dependencies.isEmpty()) {
509                 StringBuffer JavaDoc message = new StringBuffer JavaDoc();
510                 Iterator JavaDoc it = dependencies.iterator();
511                 while (it.hasNext()) {
512                     message.append(" ").append(((CmsModuleDependency)it.next()).getName()).append("\r\n");
513                 }
514                 throw new CmsConfigurationException(Messages.get().container(
515                     Messages.ERR_MOD_DEPENDENCIES_2,
516                     moduleName,
517                     message.toString()));
518             }
519             try {
520                 I_CmsModuleAction moduleAction = module.getActionInstance();
521                 // handle module action instance if initialized
522
if (moduleAction != null) {
523                     moduleAction.moduleUninstall(module);
524                 }
525             } catch (Throwable JavaDoc t) {
526                 LOG.error(Messages.get().getBundle().key(Messages.LOG_MOD_UNINSTALL_ERR_1, moduleName), t);
527             }
528         }
529
530         // now remove the module
531
module = (CmsModule)m_modules.remove(moduleName);
532
533         CmsProject previousProject = cms.getRequestContext().currentProject();
534         try {
535
536             CmsProject deleteProject = null;
537
538             try {
539                 // try to read a (leftover) module delete project
540
deleteProject = cms.readProject(Messages.get().getBundle(cms.getRequestContext().getLocale()).key(
541                     Messages.GUI_DELETE_MODULE_PROJECT_NAME_1,
542                     new Object JavaDoc[] {moduleName}));
543             } catch (CmsException e) {
544                 // create a Project to delete the module
545
deleteProject = cms.createProject(
546                     Messages.get().getBundle(cms.getRequestContext().getLocale()).key(
547                         Messages.GUI_DELETE_MODULE_PROJECT_NAME_1,
548                         new Object JavaDoc[] {moduleName}),
549                     Messages.get().getBundle(cms.getRequestContext().getLocale()).key(
550                         Messages.GUI_DELETE_MODULE_PROJECT_DESC_1,
551                         new Object JavaDoc[] {moduleName}),
552                     OpenCms.getDefaultUsers().getGroupAdministrators(),
553                     OpenCms.getDefaultUsers().getGroupAdministrators(),
554                     CmsProject.PROJECT_TYPE_TEMPORARY);
555             }
556
557             cms.getRequestContext().setCurrentProject(deleteProject);
558
559             // copy the module resources to the project
560
List JavaDoc projectFiles = module.getResources();
561             for (int i = 0; i < projectFiles.size(); i++) {
562                 try {
563                     String JavaDoc resourceName = (String JavaDoc)projectFiles.get(i);
564                     if (cms.existsResource(resourceName)) {
565                         cms.copyResourceToProject(resourceName);
566                     }
567                 } catch (CmsException e) {
568                     // may happen if the resource has already been deleted
569
LOG.error(
570                         Messages.get().getBundle().key(Messages.LOG_MOVE_RESOURCE_FAILED_1, projectFiles.get(i)),
571                         e);
572                     report.println(e);
573                 }
574             }
575
576             report.print(Messages.get().container(Messages.RPT_DELETE_MODULE_BEGIN_0), I_CmsReport.FORMAT_HEADLINE);
577             report.println(org.opencms.report.Messages.get().container(
578                 org.opencms.report.Messages.RPT_ARGUMENT_HTML_ITAG_1,
579                 moduleName), I_CmsReport.FORMAT_HEADLINE);
580
581             // move through all module resources and delete them
582
for (int i = 0; i < module.getResources().size(); i++) {
583                 String JavaDoc currentResource = null;
584                 try {
585                     currentResource = (String JavaDoc)module.getResources().get(i);
586                     if (LOG.isDebugEnabled()) {
587                         LOG.debug(Messages.get().getBundle().key(Messages.LOG_DEL_MOD_RESOURCE_1, currentResource));
588                     }
589                     if (cms.existsResource(currentResource)) {
590                         // lock the resource
591
cms.lockResource(currentResource);
592                         // delete the resource
593
cms.deleteResource(currentResource, CmsResource.DELETE_PRESERVE_SIBLINGS);
594                         // update the report
595

596                         report.print(Messages.get().container(Messages.RPT_DELETE_0), I_CmsReport.FORMAT_NOTE);
597                         report.println(org.opencms.report.Messages.get().container(
598                             org.opencms.report.Messages.RPT_ARGUMENT_1,
599                             currentResource));
600                         // unlock the resource (so it gets deleted with next publish)
601
cms.unlockResource(currentResource);
602                     }
603                 } catch (CmsException e) {
604                     // ignore the exception and delete the next resource
605
LOG.error(Messages.get().getBundle().key(Messages.LOG_DEL_MOD_EXC_1, currentResource), e);
606                     report.println(e);
607                 }
608             }
609
610             report.println(Messages.get().container(Messages.RPT_PUBLISH_PROJECT_BEGIN_0), I_CmsReport.FORMAT_HEADLINE);
611
612             // now unlock and publish the project
613
cms.unlockProject(deleteProject.getId());
614             cms.publishProject(report);
615
616             report.println(Messages.get().container(Messages.RPT_PUBLISH_PROJECT_END_0), I_CmsReport.FORMAT_HEADLINE);
617             report.println(Messages.get().container(Messages.RPT_DELETE_MODULE_END_0), I_CmsReport.FORMAT_HEADLINE);
618         } catch (CmsException e) {
619             throw new CmsConfigurationException(e.getMessageContainer(), e);
620         } finally {
621             cms.getRequestContext().setCurrentProject(previousProject);
622         }
623
624         // initialize the export points (removes export points from deleted module)
625
initModuleExportPoints();
626
627         // update the configuration
628
updateModuleConfiguration();
629
630         // reinit the manager is nescessary
631
if (removeResourceTypes) {
632             OpenCms.getResourceManager().initialize(cms);
633         }
634     }
635
636     /**
637      * Returns a list of installed modules.<p>
638      *
639      * @return a list of <code>{@link CmsModule}</code> objects
640      */

641     public List JavaDoc getAllInstalledModules() {
642
643         return new ArrayList JavaDoc(m_modules.values());
644     }
645
646     /**
647      * Returns the (immutable) list of configured module export points.<p>
648      *
649      * @return the (immutable) list of configured module export points
650      * @see CmsExportPoint
651      */

652     public Set JavaDoc getExportPoints() {
653
654         return m_moduleExportPoints;
655     }
656
657     /**
658      * Returns the module with the given module name,
659      * or <code>null</code> if no module with the given name is configured.<p>
660      *
661      * @param name the name of the module to return
662      * @return the module with the given module name
663      */

664     public CmsModule getModule(String JavaDoc name) {
665
666         return (CmsModule)m_modules.get(name);
667     }
668
669     /**
670      * Returns the set of names of all the installed modules.<p>
671      *
672      * @return the set of names of all the installed modules
673      */

674     public Set JavaDoc getModuleNames() {
675
676         synchronized (m_modules) {
677             return new HashSet JavaDoc(m_modules.keySet());
678         }
679     }
680
681     /**
682      * Checks if this module manager has a module with the given name installed.<p>
683      *
684      * @param name the name of the module to check
685      * @return true if this module manager has a module with the given name installed
686      */

687     public boolean hasModule(String JavaDoc name) {
688
689         return m_modules.containsKey(name);
690     }
691
692     /**
693      * Initializes all module instance classes managed in this module manager.<p>
694      *
695      * @param cms an initialized CmsObject with "manage modules" role permissions
696      * @param configurationManager the initialized OpenCms configuration manager
697      *
698      * @throws CmsRoleViolationException if the provided OpenCms context does not have "manage modules" role permissions
699      */

700     public synchronized void initialize(CmsObject cms, CmsConfigurationManager configurationManager)
701     throws CmsRoleViolationException {
702
703         if (OpenCms.getRunLevel() > OpenCms.RUNLEVEL_1_CORE_OBJECT) {
704             // certain test cases won't have an OpenCms context
705
cms.checkRole(CmsRole.MODULE_MANAGER);
706         }
707
708         Iterator JavaDoc it;
709         int count = 0;
710         it = m_modules.keySet().iterator();
711         while (it.hasNext()) {
712             // get the module description
713
CmsModule module = (CmsModule)m_modules.get(it.next());
714
715             if (module.getActionClass() != null) {
716                 // create module instance class
717
I_CmsModuleAction moduleAction = module.getActionInstance();
718                 if (module.getActionClass() != null) {
719                     try {
720                         moduleAction = (I_CmsModuleAction)Class.forName(module.getActionClass()).newInstance();
721                     } catch (Exception JavaDoc e) {
722                         CmsLog.INIT.info(Messages.get().getBundle().key(
723                             Messages.INIT_CREATE_INSTANCE_FAILED_1,
724                             module.getName()), e);
725                     }
726                 }
727                 if (moduleAction != null) {
728                     count++;
729                     module.setActionInstance(moduleAction);
730                     if (CmsLog.INIT.isInfoEnabled()) {
731                         CmsLog.INIT.info(Messages.get().getBundle().key(
732                             Messages.INIT_INITIALIZE_MOD_CLASS_1,
733                             moduleAction.getClass().getName()));
734                     }
735                     try {
736                         // create a copy of the adminCms so that each module instance does have
737
// it's own context, a shared context might introduce side - effects
738
CmsObject adminCmsCopy = OpenCms.initCmsObject(cms);
739                         // initialize the module
740
moduleAction.initialize(adminCmsCopy, configurationManager, module);
741                     } catch (Throwable JavaDoc t) {
742                         LOG.error(Messages.get().getBundle().key(
743                             Messages.LOG_INSTANCE_INIT_ERR_1,
744                             moduleAction.getClass().getName()), t);
745                     }
746                 }
747             }
748         }
749
750         // initialize the export points
751
initModuleExportPoints();
752
753         if (CmsLog.INIT.isInfoEnabled()) {
754             CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_NUM_CLASSES_INITIALIZED_1, new Integer JavaDoc(count)));
755         }
756     }
757
758     /**
759      * Shuts down all module instance classes managed in this module manager.<p>
760      */

761     public synchronized void shutDown() {
762
763         int count = 0;
764         Iterator JavaDoc it = getModuleNames().iterator();
765         while (it.hasNext()) {
766             String JavaDoc moduleName = (String JavaDoc)it.next();
767             // get the module
768
CmsModule module = (CmsModule)m_modules.get(moduleName);
769             if (module == null) {
770                 continue;
771             }
772             // get the module action instance
773
I_CmsModuleAction moduleAction = module.getActionInstance();
774             if (moduleAction == null) {
775                 continue;
776             }
777
778             count++;
779             if (CmsLog.INIT.isInfoEnabled()) {
780                 CmsLog.INIT.info(Messages.get().getBundle().key(
781                     Messages.INIT_SHUTDOWN_MOD_CLASS_1,
782                     moduleAction.getClass().getName()));
783             }
784             try {
785                 // shut down the module
786
moduleAction.shutDown(module);
787             } catch (Throwable JavaDoc t) {
788                 LOG.error(Messages.get().getBundle().key(
789                     Messages.LOG_INSTANCE_SHUTDOWN_ERR_1,
790                     moduleAction.getClass().getName()), t);
791             }
792         }
793
794         if (CmsLog.INIT.isInfoEnabled()) {
795             CmsLog.INIT.info(Messages.get().getBundle().key(
796                 Messages.INIT_SHUTDOWN_NUM_MOD_CLASSES_1,
797                 new Integer JavaDoc(count)));
798         }
799
800         if (CmsLog.INIT.isInfoEnabled()) {
801             CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_SHUTDOWN_1, this.getClass().getName()));
802         }
803     }
804
805     /**
806      * Updates a already configured module with new values.<p>
807      *
808      * @param cms must be initialized with "Admin" permissions
809      * @param module the module to update
810      *
811      * @throws CmsRoleViolationException if the required module manager role permissions are not available
812      * @throws CmsConfigurationException if a module with this name is not available for updateing
813      */

814     public synchronized void updateModule(CmsObject cms, CmsModule module)
815     throws CmsRoleViolationException, CmsConfigurationException {
816
817         // check for module manager role permissions
818
cms.checkRole(CmsRole.MODULE_MANAGER);
819
820         CmsModule oldModule = (CmsModule)m_modules.get(module.getName());
821
822         if (oldModule == null) {
823             // module is not currently configured, no update possible
824
throw new CmsConfigurationException(Messages.get().container(Messages.ERR_OLD_MOD_ERR_1, module.getName()));
825         }
826
827         if (LOG.isInfoEnabled()) {
828             LOG.info(Messages.get().getBundle().key(Messages.LOG_MOD_UPDATE_1, module.getName()));
829         }
830
831         if (oldModule.getVersion().compareTo(module.getVersion()) == 0) {
832             // module version has not changed - auto increment version number
833
module.getVersion().increment();
834         }
835         // indicate that the version number was recently updated
836
module.getVersion().setUpdated(true);
837
838         // initialize (freeze) the module
839
module.initialize(cms);
840
841         // replace old version of module with new version
842
m_modules.put(module.getName(), module);
843
844         try {
845             I_CmsModuleAction moduleAction = oldModule.getActionInstance();
846             // handle module action instance if initialized
847
if (moduleAction != null) {
848                 moduleAction.moduleUpdate(module);
849                 // set the old action instance
850
// the new action instance will be used after a system restart
851
module.setActionInstance(moduleAction);
852             }
853         } catch (Throwable JavaDoc t) {
854             LOG.error(Messages.get().getBundle().key(Messages.LOG_INSTANCE_UPDATE_ERR_1, module.getName()), t);
855         }
856
857         // initialize the export points
858
initModuleExportPoints();
859
860         // update the configuration
861
updateModuleConfiguration();
862     }
863
864     /**
865      * Initializes the list of esport points from all configured modules.<p>
866      */

867     private synchronized void initModuleExportPoints() {
868
869         Set JavaDoc exportPoints = new HashSet JavaDoc();
870         Iterator JavaDoc i = m_modules.values().iterator();
871         while (i.hasNext()) {
872             CmsModule module = (CmsModule)i.next();
873             List JavaDoc moduleExportPoints = module.getExportPoints();
874             for (int j = 0; j < moduleExportPoints.size(); j++) {
875                 CmsExportPoint point = (CmsExportPoint)moduleExportPoints.get(j);
876                 if (exportPoints.contains(point)) {
877                     if (LOG.isWarnEnabled()) {
878                         LOG.warn(Messages.get().getBundle().key(
879                             Messages.LOG_DUPLICATE_EXPORT_POINT_2,
880                             point,
881                             module.getName()));
882                     }
883                 } else {
884                     exportPoints.add(point);
885                     if (LOG.isDebugEnabled()) {
886                         LOG.debug(Messages.get().getBundle().key(
887                             Messages.LOG_ADD_EXPORT_POINT_2,
888                             point,
889                             module.getName()));
890                     }
891                 }
892             }
893         }
894         m_moduleExportPoints = Collections.unmodifiableSet(exportPoints);
895     }
896
897     /**
898      * Updates the module configuration.<p>
899      */

900     private void updateModuleConfiguration() {
901
902         OpenCms.writeConfiguration(CmsModuleConfiguration.class);
903     }
904 }
Popular Tags