All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.opencms.module.CmsModuleManager Maven / Gradle / Ivy

Go to download

OpenCms is an enterprise-ready, easy to use website content management system based on Java and XML technology. Offering a complete set of features, OpenCms helps content managers worldwide to create and maintain beautiful websites fast and efficiently.

There is a newer version: 18.0
Show newest version
/*
 * This library is part of OpenCms -
 * the Open Source Content Management System
 *
 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * For further information about Alkacon Software GmbH & Co. KG, please see the
 * company website: http://www.alkacon.com
 *
 * For further information about OpenCms, please see the
 * project website: http://www.opencms.org
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package org.opencms.module;

import org.opencms.configuration.CmsConfigurationException;
import org.opencms.configuration.CmsConfigurationManager;
import org.opencms.configuration.CmsModuleConfiguration;
import org.opencms.db.CmsExportPoint;
import org.opencms.file.CmsObject;
import org.opencms.file.CmsProject;
import org.opencms.file.CmsResource;
import org.opencms.i18n.CmsMessageContainer;
import org.opencms.importexport.CmsImportExportManager;
import org.opencms.lock.CmsLock;
import org.opencms.lock.CmsLockException;
import org.opencms.lock.CmsLockFilter;
import org.opencms.main.CmsException;
import org.opencms.main.CmsIllegalArgumentException;
import org.opencms.main.CmsIllegalStateException;
import org.opencms.main.CmsLog;
import org.opencms.main.CmsRuntimeException;
import org.opencms.main.OpenCms;
import org.opencms.report.I_CmsReport;
import org.opencms.security.CmsRole;
import org.opencms.security.CmsRoleViolationException;
import org.opencms.security.CmsSecurityException;
import org.opencms.util.CmsStringUtil;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.logging.Log;

/**
 * Manages the modules of an OpenCms installation.

* * @since 6.0.0 */ public class CmsModuleManager { /** Indicates dependency check for module deletion. */ public static final int DEPENDENCY_MODE_DELETE = 0; /** Indicates dependency check for module import. */ public static final int DEPENDENCY_MODE_IMPORT = 1; /** The log object for this class. */ private static final Log LOG = CmsLog.getLog(CmsModuleManager.class); /** The import/export repository. */ private CmsModuleImportExportRepository m_importExportRepository = new CmsModuleImportExportRepository(); /** The list of module export points. */ private Set m_moduleExportPoints; /** The map of configured modules. */ private Map m_modules; /** * Basic constructor.

* * @param configuredModules the list of configured modules */ public CmsModuleManager(List configuredModules) { if (CmsLog.INIT.isInfoEnabled()) { CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_MOD_MANAGER_CREATED_0)); } m_modules = new Hashtable(); for (int i = 0; i < configuredModules.size(); i++) { CmsModule module = configuredModules.get(i); m_modules.put(module.getName(), module); if (CmsLog.INIT.isInfoEnabled()) { CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_MOD_CONFIGURED_1, module.getName())); } } if (CmsLog.INIT.isInfoEnabled()) { CmsLog.INIT.info( Messages.get().getBundle().key(Messages.INIT_NUM_MODS_CONFIGURED_1, new Integer(m_modules.size()))); } m_moduleExportPoints = Collections.emptySet(); } /** * Returns a map of dependencies.

* * The module dependencies are get from the installed modules or * from the module manifest.xml files found in the given FRS path.

* * Two types of dependency lists can be generated:
*

    *
  • Forward dependency lists: a list of modules that depends on a module
  • *
  • Backward dependency lists: a list of modules that a module depends on
  • *
* * @param rfsAbsPath a RFS absolute path to search for modules, or null to use the installed modules * @param mode if true a list of forward dependency is build, is not a list of backward dependency * * @return a Map of module names as keys and a list of dependency names as values * * @throws CmsConfigurationException if something goes wrong */ public static Map> buildDepsForAllModules(String rfsAbsPath, boolean mode) throws CmsConfigurationException { Map> ret = new HashMap>(); List modules; if (rfsAbsPath == null) { modules = OpenCms.getModuleManager().getAllInstalledModules(); } else { modules = new ArrayList(getAllModulesFromPath(rfsAbsPath).keySet()); } Iterator itMods = modules.iterator(); while (itMods.hasNext()) { CmsModule module = itMods.next(); // if module a depends on module b, and module c depends also on module b: // build a map with a list containing "a" and "c" keyed by "b" to get a // list of modules depending on module "b"... Iterator itDeps = module.getDependencies().iterator(); while (itDeps.hasNext()) { CmsModuleDependency dependency = itDeps.next(); // module dependency package name String moduleDependencyName = dependency.getName(); if (mode) { // get the list of dependent modules List moduleDependencies = ret.get(moduleDependencyName); if (moduleDependencies == null) { // build a new list if "b" has no dependent modules yet moduleDependencies = new ArrayList(); ret.put(moduleDependencyName, moduleDependencies); } // add "a" as a module depending on "b" moduleDependencies.add(module.getName()); } else { List moduleDependencies = ret.get(module.getName()); if (moduleDependencies == null) { moduleDependencies = new ArrayList(); ret.put(module.getName(), moduleDependencies); } moduleDependencies.add(dependency.getName()); } } } itMods = modules.iterator(); while (itMods.hasNext()) { CmsModule module = itMods.next(); if (ret.get(module.getName()) == null) { ret.put(module.getName(), new ArrayList()); } } return ret; } /** * Returns a map of dependencies between the given modules.

* * The module dependencies are get from the installed modules or * from the module manifest.xml files found in the given FRS path.

* * Two types of dependency lists can be generated:
*

    *
  • Forward dependency lists: a list of modules that depends on a module
  • *
  • Backward dependency lists: a list of modules that a module depends on
  • *
* * @param moduleNames a list of module names * @param rfsAbsPath a RFS absolute path to search for modules, or null to use the installed modules * @param mode if true a list of forward dependency is build, is not a list of backward dependency * * @return a Map of module names as keys and a list of dependency names as values * * @throws CmsConfigurationException if something goes wrong */ public static Map> buildDepsForModulelist( List moduleNames, String rfsAbsPath, boolean mode) throws CmsConfigurationException { Map> ret = buildDepsForAllModules(rfsAbsPath, mode); Iterator itMods; if (rfsAbsPath == null) { itMods = OpenCms.getModuleManager().getAllInstalledModules().iterator(); } else { itMods = getAllModulesFromPath(rfsAbsPath).keySet().iterator(); } while (itMods.hasNext()) { CmsModule module = itMods.next(); if (!moduleNames.contains(module.getName())) { Iterator> itDeps = ret.values().iterator(); while (itDeps.hasNext()) { List dependencies = itDeps.next(); dependencies.remove(module.getName()); } ret.remove(module.getName()); } } return ret; } /** * Returns a map of modules found in the given RFS absolute path.

* * @param rfsAbsPath the path to look for module distributions * * @return a map of {@link CmsModule} objects for keys and filename for values * * @throws CmsConfigurationException if something goes wrong */ public static Map getAllModulesFromPath(String rfsAbsPath) throws CmsConfigurationException { Map modules = new HashMap(); if (rfsAbsPath == null) { return modules; } File folder = new File(rfsAbsPath); if (folder.exists()) { // list all child resources in the given folder File[] folderFiles = folder.listFiles(); if (folderFiles != null) { for (int i = 0; i < folderFiles.length; i++) { File moduleFile = folderFiles[i]; if (moduleFile.isFile() && !(moduleFile.getAbsolutePath().toLowerCase().endsWith(".zip"))) { // skip non-ZIP files continue; } if (moduleFile.isDirectory()) { File manifest = new File(moduleFile, CmsImportExportManager.EXPORT_MANIFEST); if (!manifest.exists() || !manifest.canRead()) { // skip unused directories continue; } } modules.put( CmsModuleImportExportHandler.readModuleFromImport(moduleFile.getAbsolutePath()), moduleFile.getName()); } } } return modules; } /** * Sorts a given list of module names by dependencies, * so that the resulting list can be imported in that given order, * that means modules without dependencies first.

* * The module dependencies are get from the installed modules or * from the module manifest.xml files found in the given FRS path.

* * @param moduleNames a list of module names * @param rfsAbsPath a RFS absolute path to search for modules, or null to use the installed modules * * @return a sorted list of module names * * @throws CmsConfigurationException if something goes wrong */ public static List topologicalSort(List moduleNames, String rfsAbsPath) throws CmsConfigurationException { List modules = new ArrayList(moduleNames); List retList = new ArrayList(); Map> moduleDependencies = buildDepsForModulelist(moduleNames, rfsAbsPath, true); boolean finished = false; while (!finished) { finished = true; Iterator itMods = modules.iterator(); while (itMods.hasNext()) { String moduleName = itMods.next(); List deps = moduleDependencies.get(moduleName); if ((deps == null) || deps.isEmpty()) { retList.add(moduleName); Iterator> itDeps = moduleDependencies.values().iterator(); while (itDeps.hasNext()) { List dependencies = itDeps.next(); dependencies.remove(moduleName); } finished = false; itMods.remove(); } } } if (!modules.isEmpty()) { throw new CmsIllegalStateException( Messages.get().container(Messages.ERR_MODULE_DEPENDENCY_CYCLE_1, modules.toString())); } Collections.reverse(retList); return retList; } /** * Adds a new module to the module manager.

* * @param cms must be initialized with "Admin" permissions * @param module the module to add * * @throws CmsSecurityException if the required permissions are not available (i.e. no "Admin" CmsObject has been provided) * @throws CmsConfigurationException if a module with this name is already configured */ public synchronized void addModule(CmsObject cms, CmsModule module) throws CmsSecurityException, CmsConfigurationException { // check the role permissions OpenCms.getRoleManager().checkRole(cms, CmsRole.DATABASE_MANAGER); if (m_modules.containsKey(module.getName())) { // module is currently configured, no create possible throw new CmsConfigurationException( Messages.get().container(Messages.ERR_MODULE_ALREADY_CONFIGURED_1, module.getName())); } if (LOG.isInfoEnabled()) { LOG.info(Messages.get().getBundle().key(Messages.LOG_CREATE_NEW_MOD_1, module.getName())); } // initialize the module module.initialize(cms); m_modules.put(module.getName(), module); try { I_CmsModuleAction moduleAction = module.getActionInstance(); // handle module action instance if initialized if (moduleAction != null) { moduleAction.moduleUpdate(module); } } catch (Throwable t) { LOG.error(Messages.get().getBundle().key(Messages.LOG_MOD_UPDATE_ERR_1, module.getName()), t); } // initialize the export points initModuleExportPoints(); // update the configuration updateModuleConfiguration(); } /** * Checks if a modules dependencies are fulfilled.

* * The possible values for the mode parameter are:

*
{@link #DEPENDENCY_MODE_DELETE}
*
Check for module deleting, i.e. are other modules dependent on the * given module?
*
{@link #DEPENDENCY_MODE_IMPORT}
*
Check for module importing, i.e. are all dependencies required by the given * module available?
* * @param module the module to check the dependencies for * @param mode the dependency check mode * @return a list of dependencies that are not fulfilled, if empty all dependencies are fulfilled */ public List checkDependencies(CmsModule module, int mode) { List result = new ArrayList(); if (mode == DEPENDENCY_MODE_DELETE) { // delete mode, check if other modules depend on this module Iterator i = m_modules.values().iterator(); while (i.hasNext()) { CmsModule otherModule = i.next(); CmsModuleDependency dependency = otherModule.checkDependency(module); if (dependency != null) { // dependency found, add to list result.add(new CmsModuleDependency(otherModule.getName(), otherModule.getVersion())); } } } else if (mode == DEPENDENCY_MODE_IMPORT) { // import mode, check if all module dependencies are fulfilled Iterator i = m_modules.values().iterator(); // add all dependencies that must be found result.addAll(module.getDependencies()); while (i.hasNext() && (result.size() > 0)) { CmsModule otherModule = i.next(); CmsModuleDependency dependency = module.checkDependency(otherModule); if (dependency != null) { // dependency found, remove from list result.remove(dependency); } } } else { // invalid mode selected throw new CmsRuntimeException( Messages.get().container(Messages.ERR_CHECK_DEPENDENCY_INVALID_MODE_1, new Integer(mode))); } return result; } /** * Checks the module selection list for consistency, that means * that if a module is selected, all its dependencies are also selected.

* * The module dependencies are get from the installed modules or * from the module manifest.xml files found in the given FRS path.

* * @param moduleNames a list of module names * @param rfsAbsPath a RFS absolute path to search for modules, or null to use the installed modules * @param forDeletion there are two modes, one for installation of modules, and one for deletion. * * @throws CmsIllegalArgumentException if the module list is not consistent * @throws CmsConfigurationException if something goes wrong */ public void checkModuleSelectionList(List moduleNames, String rfsAbsPath, boolean forDeletion) throws CmsIllegalArgumentException, CmsConfigurationException { Map> moduleDependencies = buildDepsForAllModules(rfsAbsPath, forDeletion); Iterator itMods = moduleNames.iterator(); while (itMods.hasNext()) { String moduleName = itMods.next(); List dependencies = moduleDependencies.get(moduleName); if (dependencies != null) { List depModules = new ArrayList(dependencies); depModules.removeAll(moduleNames); if (!depModules.isEmpty()) { throw new CmsIllegalArgumentException( Messages.get().container( Messages.ERR_MODULE_SELECTION_INCONSISTENT_2, moduleName, depModules.toString())); } } } } /** * Deletes a module from the configuration.

* * @param cms must be initialized with "Admin" permissions * @param moduleName the name of the module to delete * @param replace indicates if the module is replaced (true) or finally deleted (false) * @param report the report to print progress messages to * * @throws CmsRoleViolationException if the required module manager role permissions are not available * @throws CmsConfigurationException if a module with this name is not available for deleting * @throws CmsLockException if the module resources can not be locked */ public synchronized void deleteModule( CmsObject cms, String moduleName, boolean replace, boolean preserveLibs, I_CmsReport report) throws CmsRoleViolationException, CmsConfigurationException, CmsLockException { // check for module manager role permissions OpenCms.getRoleManager().checkRole(cms, CmsRole.DATABASE_MANAGER); if (!m_modules.containsKey(moduleName)) { // module is not currently configured, no update possible throw new CmsConfigurationException( Messages.get().container(Messages.ERR_MODULE_NOT_CONFIGURED_1, moduleName)); } if (LOG.isInfoEnabled()) { LOG.info(Messages.get().getBundle().key(Messages.LOG_DEL_MOD_1, moduleName)); } CmsModule module = m_modules.get(moduleName); String importSite = module.getImportSite(); if (!CmsStringUtil.isEmptyOrWhitespaceOnly(importSite)) { CmsObject newCms; try { newCms = OpenCms.initCmsObject(cms); newCms.getRequestContext().setSiteRoot(importSite); cms = newCms; } catch (CmsException e) { LOG.error(e.getLocalizedMessage(), e); } } if (!replace) { // module is deleted, not replaced // perform dependency check List dependencies = checkDependencies(module, DEPENDENCY_MODE_DELETE); if (!dependencies.isEmpty()) { StringBuffer message = new StringBuffer(); Iterator it = dependencies.iterator(); while (it.hasNext()) { message.append(" ").append(it.next().getName()).append("\r\n"); } throw new CmsConfigurationException( Messages.get().container(Messages.ERR_MOD_DEPENDENCIES_2, moduleName, message.toString())); } try { I_CmsModuleAction moduleAction = module.getActionInstance(); // handle module action instance if initialized if (moduleAction != null) { moduleAction.moduleUninstall(module); } } catch (Throwable t) { LOG.error(Messages.get().getBundle().key(Messages.LOG_MOD_UNINSTALL_ERR_1, moduleName), t); report.println( Messages.get().container(Messages.LOG_MOD_UNINSTALL_ERR_1, moduleName), I_CmsReport.FORMAT_WARNING); } } boolean removeResourceTypes = !module.getResourceTypes().isEmpty(); if (removeResourceTypes) { // mark the resource manager to reinitialize if necessary OpenCms.getWorkplaceManager().removeExplorerTypeSettings(module); } CmsProject previousProject = cms.getRequestContext().getCurrentProject(); // try to create a new offline project for deletion CmsProject deleteProject = null; try { // try to read a (leftover) module delete project deleteProject = cms.readProject( Messages.get().getBundle(cms.getRequestContext().getLocale()).key( Messages.GUI_DELETE_MODULE_PROJECT_NAME_1, new Object[] {moduleName})); } catch (CmsException e) { try { // create a Project to delete the module deleteProject = cms.createProject( Messages.get().getBundle(cms.getRequestContext().getLocale()).key( Messages.GUI_DELETE_MODULE_PROJECT_NAME_1, new Object[] {moduleName}), Messages.get().getBundle(cms.getRequestContext().getLocale()).key( Messages.GUI_DELETE_MODULE_PROJECT_DESC_1, new Object[] {moduleName}), OpenCms.getDefaultUsers().getGroupAdministrators(), OpenCms.getDefaultUsers().getGroupAdministrators(), CmsProject.PROJECT_TYPE_TEMPORARY); } catch (CmsException e1) { throw new CmsConfigurationException(e1.getMessageContainer(), e1); } } try { cms.getRequestContext().setCurrentProject(deleteProject); // check locks List lockedResources = new ArrayList(); CmsLockFilter filter1 = CmsLockFilter.FILTER_ALL.filterNotLockableByUser( cms.getRequestContext().getCurrentUser()); CmsLockFilter filter2 = CmsLockFilter.FILTER_INHERITED; List moduleResources = module.getResources(); for (int iLock = 0; iLock < moduleResources.size(); iLock++) { String resourceName = moduleResources.get(iLock); try { lockedResources.addAll(cms.getLockedResources(resourceName, filter1)); lockedResources.addAll(cms.getLockedResources(resourceName, filter2)); } catch (CmsException e) { // may happen if the resource has already been deleted if (LOG.isDebugEnabled()) { LOG.debug(e.getMessageContainer(), e); } report.println(e.getMessageContainer(), I_CmsReport.FORMAT_WARNING); } } if (!lockedResources.isEmpty()) { CmsMessageContainer msg = Messages.get().container( Messages.ERR_DELETE_MODULE_CHECK_LOCKS_2, moduleName, CmsStringUtil.collectionAsString(lockedResources, ",")); report.addError(msg.key(cms.getRequestContext().getLocale())); report.println(msg); cms.getRequestContext().setCurrentProject(previousProject); try { cms.deleteProject(deleteProject.getUuid()); } catch (CmsException e1) { throw new CmsConfigurationException(e1.getMessageContainer(), e1); } throw new CmsLockException(msg); } } finally { cms.getRequestContext().setCurrentProject(previousProject); } // now remove the module module = m_modules.remove(moduleName); if (preserveLibs) { // to preserve the module libs, remove the responsible export points, before deleting module resources Set exportPoints = new HashSet(m_moduleExportPoints); Iterator it = exportPoints.iterator(); while (it.hasNext()) { CmsExportPoint point = it.next(); if ((point.getUri().endsWith(module.getName() + "/lib/") || point.getUri().endsWith(module.getName() + "/lib")) && point.getConfiguredDestination().equals("WEB-INF/lib/")) { it.remove(); } } m_moduleExportPoints = Collections.unmodifiableSet(exportPoints); } try { cms.getRequestContext().setCurrentProject(deleteProject); // copy the module resources to the project List moduleResources = CmsModule.calculateModuleResources(cms, module); for (CmsResource resource : moduleResources) { try { cms.copyResourceToProject(resource); } catch (CmsException e) { // may happen if the resource has already been deleted if (LOG.isDebugEnabled()) { LOG.debug( Messages.get().getBundle().key( Messages.LOG_MOVE_RESOURCE_FAILED_1, cms.getSitePath(resource))); } report.println(e.getMessageContainer(), I_CmsReport.FORMAT_WARNING); } } report.print(Messages.get().container(Messages.RPT_DELETE_MODULE_BEGIN_0), I_CmsReport.FORMAT_HEADLINE); report.println( org.opencms.report.Messages.get().container( org.opencms.report.Messages.RPT_ARGUMENT_HTML_ITAG_1, moduleName), I_CmsReport.FORMAT_HEADLINE); // move through all module resources and delete them for (CmsResource resource : moduleResources) { String sitePath = cms.getSitePath(resource); try { if (LOG.isDebugEnabled()) { LOG.debug(Messages.get().getBundle().key(Messages.LOG_DEL_MOD_RESOURCE_1, sitePath)); } CmsLock lock = cms.getLock(resource); if (lock.isUnlocked()) { // lock the resource cms.lockResource(resource); } else if (lock.isLockableBy(cms.getRequestContext().getCurrentUser())) { // steal the resource cms.changeLock(resource); } if (!resource.getState().isDeleted()) { // delete the resource cms.deleteResource(sitePath, CmsResource.DELETE_PRESERVE_SIBLINGS); } // update the report report.print(Messages.get().container(Messages.RPT_DELETE_0), I_CmsReport.FORMAT_NOTE); report.println( org.opencms.report.Messages.get().container( org.opencms.report.Messages.RPT_ARGUMENT_1, sitePath)); if (!resource.getState().isNew()) { // unlock the resource (so it gets deleted with next publish) cms.unlockResource(resource); } } catch (CmsException e) { // ignore the exception and delete the next resource LOG.error(Messages.get().getBundle().key(Messages.LOG_DEL_MOD_EXC_1, sitePath), e); report.println(e.getMessageContainer(), I_CmsReport.FORMAT_WARNING); } } report.println(Messages.get().container(Messages.RPT_PUBLISH_PROJECT_BEGIN_0), I_CmsReport.FORMAT_HEADLINE); // now unlock and publish the project cms.unlockProject(deleteProject.getUuid()); OpenCms.getPublishManager().publishProject(cms, report); OpenCms.getPublishManager().waitWhileRunning(); report.println(Messages.get().container(Messages.RPT_PUBLISH_PROJECT_END_0), I_CmsReport.FORMAT_HEADLINE); report.println(Messages.get().container(Messages.RPT_DELETE_MODULE_END_0), I_CmsReport.FORMAT_HEADLINE); } catch (CmsException e) { throw new CmsConfigurationException(e.getMessageContainer(), e); } finally { cms.getRequestContext().setCurrentProject(previousProject); } // initialize the export points (removes export points from deleted module) initModuleExportPoints(); // update the configuration updateModuleConfiguration(); // reinit the manager is necessary if (removeResourceTypes) { OpenCms.getResourceManager().initialize(cms); } } /** * Deletes a module from the configuration.

* * @param cms must be initialized with "Admin" permissions * @param moduleName the name of the module to delete * @param replace indicates if the module is replaced (true) or finally deleted (false) * @param report the report to print progress messages to * * @throws CmsRoleViolationException if the required module manager role permissions are not available * @throws CmsConfigurationException if a module with this name is not available for deleting * @throws CmsLockException if the module resources can not be locked */ public synchronized void deleteModule(CmsObject cms, String moduleName, boolean replace, I_CmsReport report) throws CmsRoleViolationException, CmsConfigurationException, CmsLockException { deleteModule(cms, moduleName, replace, false, report); } /** * Returns a list of installed modules.

* * @return a list of {@link CmsModule} objects */ public List getAllInstalledModules() { return new ArrayList(m_modules.values()); } /** * Returns the (immutable) list of configured module export points.

* * @return the (immutable) list of configured module export points * @see CmsExportPoint */ public Set getExportPoints() { return m_moduleExportPoints; } /** * Returns the importExportRepository.

* * @return the importExportRepository */ public CmsModuleImportExportRepository getImportExportRepository() { return m_importExportRepository; } /** * Returns the module with the given module name, * or null if no module with the given name is configured.

* * @param name the name of the module to return * @return the module with the given module name */ public CmsModule getModule(String name) { return m_modules.get(name); } /** * Returns the set of names of all the installed modules.

* * @return the set of names of all the installed modules */ public Set getModuleNames() { synchronized (m_modules) { return new HashSet(m_modules.keySet()); } } /** * Checks if this module manager has a module with the given name installed.

* * @param name the name of the module to check * @return true if this module manager has a module with the given name installed */ public boolean hasModule(String name) { return m_modules.containsKey(name); } /** * Initializes all module instance classes managed in this module manager.

* * @param cms an initialized CmsObject with "manage modules" role permissions * @param configurationManager the initialized OpenCms configuration manager * * @throws CmsRoleViolationException if the provided OpenCms context does not have "manage modules" role permissions */ public synchronized void initialize(CmsObject cms, CmsConfigurationManager configurationManager) throws CmsRoleViolationException { if (OpenCms.getRunLevel() > OpenCms.RUNLEVEL_1_CORE_OBJECT) { // certain test cases won't have an OpenCms context OpenCms.getRoleManager().checkRole(cms, CmsRole.DATABASE_MANAGER); } Iterator it; int count = 0; it = m_modules.keySet().iterator(); while (it.hasNext()) { // get the module description CmsModule module = m_modules.get(it.next()); if (module.getActionClass() != null) { // create module instance class I_CmsModuleAction moduleAction = module.getActionInstance(); if (module.getActionClass() != null) { try { moduleAction = (I_CmsModuleAction)Class.forName(module.getActionClass()).newInstance(); } catch (Exception e) { CmsLog.INIT.info( Messages.get().getBundle().key(Messages.INIT_CREATE_INSTANCE_FAILED_1, module.getName()), e); } } if (moduleAction != null) { count++; module.setActionInstance(moduleAction); if (CmsLog.INIT.isInfoEnabled()) { CmsLog.INIT.info( Messages.get().getBundle().key( Messages.INIT_INITIALIZE_MOD_CLASS_1, moduleAction.getClass().getName())); } try { // create a copy of the adminCms so that each module instance does have // it's own context, a shared context might introduce side - effects CmsObject adminCmsCopy = OpenCms.initCmsObject(cms); // initialize the module moduleAction.initialize(adminCmsCopy, configurationManager, module); } catch (Throwable t) { LOG.error( Messages.get().getBundle().key( Messages.LOG_INSTANCE_INIT_ERR_1, moduleAction.getClass().getName()), t); } } } } // initialize the export points initModuleExportPoints(); m_importExportRepository.initialize(cms); if (CmsLog.INIT.isInfoEnabled()) { CmsLog.INIT.info( Messages.get().getBundle().key(Messages.INIT_NUM_CLASSES_INITIALIZED_1, new Integer(count))); } } /** * Shuts down all module instance classes managed in this module manager.

*/ public synchronized void shutDown() { int count = 0; Iterator it = getModuleNames().iterator(); while (it.hasNext()) { String moduleName = it.next(); // get the module CmsModule module = m_modules.get(moduleName); if (module == null) { continue; } // get the module action instance I_CmsModuleAction moduleAction = module.getActionInstance(); if (moduleAction == null) { continue; } count++; if (CmsLog.INIT.isInfoEnabled()) { CmsLog.INIT.info( Messages.get().getBundle().key( Messages.INIT_SHUTDOWN_MOD_CLASS_1, moduleAction.getClass().getName())); } try { // shut down the module moduleAction.shutDown(module); } catch (Throwable t) { LOG.error( Messages.get().getBundle().key( Messages.LOG_INSTANCE_SHUTDOWN_ERR_1, moduleAction.getClass().getName()), t); } } if (CmsLog.INIT.isInfoEnabled()) { CmsLog.INIT.info( Messages.get().getBundle().key(Messages.INIT_SHUTDOWN_NUM_MOD_CLASSES_1, new Integer(count))); } if (CmsLog.INIT.isInfoEnabled()) { CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_SHUTDOWN_1, this.getClass().getName())); } } /** * Updates a already configured module with new values.

* * @param cms must be initialized with "Admin" permissions * @param module the module to update * * @throws CmsRoleViolationException if the required module manager role permissions are not available * @throws CmsConfigurationException if a module with this name is not available for updating */ public synchronized void updateModule(CmsObject cms, CmsModule module) throws CmsRoleViolationException, CmsConfigurationException { // check for module manager role permissions OpenCms.getRoleManager().checkRole(cms, CmsRole.DATABASE_MANAGER); CmsModule oldModule = m_modules.get(module.getName()); if (oldModule == null) { // module is not currently configured, no update possible throw new CmsConfigurationException(Messages.get().container(Messages.ERR_OLD_MOD_ERR_1, module.getName())); } if (LOG.isInfoEnabled()) { LOG.info(Messages.get().getBundle().key(Messages.LOG_MOD_UPDATE_1, module.getName())); } // indicate that the version number was recently updated module.getVersion().setUpdated(true); // initialize (freeze) the module module.initialize(cms); // replace old version of module with new version m_modules.put(module.getName(), module); try { I_CmsModuleAction moduleAction = oldModule.getActionInstance(); // handle module action instance if initialized if (moduleAction != null) { moduleAction.moduleUpdate(module); // set the old action instance // the new action instance will be used after a system restart module.setActionInstance(moduleAction); } } catch (Throwable t) { LOG.error(Messages.get().getBundle().key(Messages.LOG_INSTANCE_UPDATE_ERR_1, module.getName()), t); } // initialize the export points initModuleExportPoints(); // update the configuration updateModuleConfiguration(); } /** * Initializes the list of export points from all configured modules.

*/ private synchronized void initModuleExportPoints() { Set exportPoints = new HashSet(); Iterator i = m_modules.values().iterator(); while (i.hasNext()) { CmsModule module = i.next(); List moduleExportPoints = module.getExportPoints(); for (int j = 0; j < moduleExportPoints.size(); j++) { CmsExportPoint point = moduleExportPoints.get(j); if (exportPoints.contains(point)) { if (LOG.isWarnEnabled()) { LOG.warn( Messages.get().getBundle().key( Messages.LOG_DUPLICATE_EXPORT_POINT_2, point, module.getName())); } } else { exportPoints.add(point); if (LOG.isDebugEnabled()) { LOG.debug( Messages.get().getBundle().key(Messages.LOG_ADD_EXPORT_POINT_2, point, module.getName())); } } } } m_moduleExportPoints = Collections.unmodifiableSet(exportPoints); } /** * Updates the module configuration.

*/ private void updateModuleConfiguration() { OpenCms.writeConfiguration(CmsModuleConfiguration.class); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy