Support for renaming of modules

- When a module ID changes, the old ID gets put in a list against property 'module.aliases'.
 - The tool and the repo startup detect the existing installation against the alias and perform a rename.


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@5559 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2007-04-26 08:42:19 +00:00
parent d94db4e310
commit 31efa6d4f3
10 changed files with 362 additions and 46 deletions

View File

@@ -66,7 +66,6 @@ public class ModuleComponentHelper
private static final String REGISTRY_PROPERTY_CURRENT_VERSION = "currentVersion"; private static final String REGISTRY_PROPERTY_CURRENT_VERSION = "currentVersion";
private static final String REGISTRY_PATH_COMPONENTS = "components"; private static final String REGISTRY_PATH_COMPONENTS = "components";
private static final String REGISTRY_PROPERTY_EXECUTION_DATE = "executionDate"; private static final String REGISTRY_PROPERTY_EXECUTION_DATE = "executionDate";
private static final String REGISTRY_PROPERTY_DUMMY = "dummy";
private static final String MSG_FOUND_MODULES = "module.msg.found_modules"; private static final String MSG_FOUND_MODULES = "module.msg.found_modules";
private static final String MSG_STARTING = "module.msg.starting"; private static final String MSG_STARTING = "module.msg.starting";
@@ -248,7 +247,7 @@ public class ModuleComponentHelper
// Get the IDs of all modules from the registry // Get the IDs of all modules from the registry
RegistryKey moduleKeyAllIds = new RegistryKey( RegistryKey moduleKeyAllIds = new RegistryKey(
ModuleComponentHelper.URI_MODULES_1_0, ModuleComponentHelper.URI_MODULES_1_0,
REGISTRY_PATH_MODULES, REGISTRY_PROPERTY_DUMMY); REGISTRY_PATH_MODULES, null);
Collection<String> moduleIds = registryService.getChildElements(moduleKeyAllIds); Collection<String> moduleIds = registryService.getChildElements(moduleKeyAllIds);
// Check that each module is present in the distribution // Check that each module is present in the distribution
@@ -268,13 +267,65 @@ public class ModuleComponentHelper
RegistryKey moduleKeyCurrentVersion = new RegistryKey( RegistryKey moduleKeyCurrentVersion = new RegistryKey(
ModuleComponentHelper.URI_MODULES_1_0, ModuleComponentHelper.URI_MODULES_1_0,
REGISTRY_PATH_MODULES, moduleId, REGISTRY_PROPERTY_CURRENT_VERSION); REGISTRY_PATH_MODULES, moduleId, REGISTRY_PROPERTY_CURRENT_VERSION);
VersionNumber versionCurrent = (VersionNumber) registryService.getValue(moduleKeyCurrentVersion); VersionNumber versionCurrent = (VersionNumber) registryService.getProperty(moduleKeyCurrentVersion);
// The module is missing, so warn // The module is missing, so warn
loggerService.warn(I18NUtil.getMessage(MSG_MISSING, moduleId, versionCurrent)); loggerService.warn(I18NUtil.getMessage(MSG_MISSING, moduleId, versionCurrent));
} }
} }
} }
/**
* Copies, where necessary, the module registry details from the alias details
* and removes the alias details.
*/
private void renameModule(ModuleDetails module)
{
String moduleId = module.getId();
List<String> moduleAliases = module.getAliases();
// Get the IDs of all modules from the registry
RegistryKey moduleKeyAllIds = new RegistryKey(
ModuleComponentHelper.URI_MODULES_1_0,
REGISTRY_PATH_MODULES, null);
Collection<String> registeredModuleIds = registryService.getChildElements(moduleKeyAllIds);
// Firstly, is the module installed?
if (registeredModuleIds.contains(moduleId))
{
// It is there, so we do nothing
return;
}
// Check if any of the registered modules are on the alias list
for (String moduleAlias : moduleAliases)
{
// Is this alias registered?
if (!registeredModuleIds.contains(moduleAlias))
{
// No alias registered
continue;
}
// We found an alias and have to rename it to the new module ID
RegistryKey moduleKeyNew = new RegistryKey(
ModuleComponentHelper.URI_MODULES_1_0,
REGISTRY_PATH_MODULES, moduleId, null);
RegistryKey moduleKeyOld = new RegistryKey(
ModuleComponentHelper.URI_MODULES_1_0,
REGISTRY_PATH_MODULES, moduleAlias, null);
// Copy it all
registryService.copy(moduleKeyOld, moduleKeyNew);
// Remove the source
registryService.delete(moduleKeyOld);
// Done
if (logger.isDebugEnabled())
{
logger.debug("Moved old module alias to new module ID: \n" +
" Alias: " + moduleAlias + "\n" +
" Module: " + moduleId);
}
break;
}
}
/** /**
* Does the actual work without fussing about transactions and authentication. * Does the actual work without fussing about transactions and authentication.
*/ */
@@ -283,7 +334,10 @@ public class ModuleComponentHelper
String moduleId = module.getId(); String moduleId = module.getId();
VersionNumber moduleVersion = module.getVersion(); VersionNumber moduleVersion = module.getVersion();
// First check that the module version is fundamentall compatible with the repository // Check if the module needs a rename first
renameModule(module);
// First check that the module version is fundamentally compatible with the repository
VersionNumber repoVersionNumber = descriptorService.getServerDescriptor().getVersionNumber(); VersionNumber repoVersionNumber = descriptorService.getServerDescriptor().getVersionNumber();
VersionNumber minRepoVersionNumber = module.getRepoVersionMin(); VersionNumber minRepoVersionNumber = module.getRepoVersionMin();
VersionNumber maxRepoVersionNumber = module.getRepoVersionMax(); VersionNumber maxRepoVersionNumber = module.getRepoVersionMax();
@@ -303,13 +357,13 @@ public class ModuleComponentHelper
RegistryKey moduleKeyCurrentVersion = new RegistryKey( RegistryKey moduleKeyCurrentVersion = new RegistryKey(
ModuleComponentHelper.URI_MODULES_1_0, ModuleComponentHelper.URI_MODULES_1_0,
REGISTRY_PATH_MODULES, moduleId, REGISTRY_PROPERTY_CURRENT_VERSION); REGISTRY_PATH_MODULES, moduleId, REGISTRY_PROPERTY_CURRENT_VERSION);
VersionNumber versionCurrent = (VersionNumber) registryService.getValue(moduleKeyCurrentVersion); VersionNumber versionCurrent = (VersionNumber) registryService.getProperty(moduleKeyCurrentVersion);
String msg = null; String msg = null;
if (versionCurrent == null) // There is no current version if (versionCurrent == null) // There is no current version
{ {
msg = I18NUtil.getMessage(MSG_INSTALLING, moduleId, moduleVersion); msg = I18NUtil.getMessage(MSG_INSTALLING, moduleId, moduleVersion);
// Record the install version // Record the install version
registryService.addValue(moduleKeyInstalledVersion, moduleVersion); registryService.addProperty(moduleKeyInstalledVersion, moduleVersion);
} }
else // It is an upgrade or is the same else // It is an upgrade or is the same
{ {
@@ -328,7 +382,7 @@ public class ModuleComponentHelper
} }
loggerService.info(msg); loggerService.info(msg);
// Record the current version // Record the current version
registryService.addValue(moduleKeyCurrentVersion, moduleVersion); registryService.addProperty(moduleKeyCurrentVersion, moduleVersion);
Map<String, ModuleComponent> componentsByName = getComponents(moduleId); Map<String, ModuleComponent> componentsByName = getComponents(moduleId);
for (ModuleComponent component : componentsByName.values()) for (ModuleComponent component : componentsByName.values())
@@ -387,7 +441,7 @@ public class ModuleComponentHelper
REGISTRY_PATH_MODULES, moduleId, REGISTRY_PATH_COMPONENTS, name, REGISTRY_PROPERTY_EXECUTION_DATE); REGISTRY_PATH_MODULES, moduleId, REGISTRY_PATH_COMPONENTS, name, REGISTRY_PROPERTY_EXECUTION_DATE);
// Check if the component has been executed // Check if the component has been executed
Date executionDate = (Date) registryService.getValue(executionDateKey); Date executionDate = (Date) registryService.getProperty(executionDateKey);
if (executionDate != null && component.isExecuteOnceOnly()) if (executionDate != null && component.isExecuteOnceOnly())
{ {
// It has been executed and is scheduled for a single execution - leave it // It has been executed and is scheduled for a single execution - leave it
@@ -410,7 +464,7 @@ public class ModuleComponentHelper
component.execute(); component.execute();
// Keep track of it in the registry and in this run // Keep track of it in the registry and in this run
executedComponents.add(component); executedComponents.add(component);
registryService.addValue(executionDateKey, new Date()); registryService.addProperty(executionDateKey, new Date());
// Done // Done
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
{ {

View File

@@ -27,7 +27,9 @@ package org.alfresco.repo.module;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Properties; import java.util.Properties;
import java.util.StringTokenizer;
import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.service.cmr.module.ModuleDetails; import org.alfresco.service.cmr.module.ModuleDetails;
@@ -48,6 +50,7 @@ import org.alfresco.util.VersionNumber;
public class ModuleDetailsImpl implements ModuleDetails public class ModuleDetailsImpl implements ModuleDetails
{ {
private String id; private String id;
private List<String> aliases;
private VersionNumber version; private VersionNumber version;
private String title; private String title;
private String description; private String description;
@@ -56,53 +59,102 @@ public class ModuleDetailsImpl implements ModuleDetails
private Date installDate; private Date installDate;
private ModuleInstallState installState; private ModuleInstallState installState;
/** /**
* Private constructor to set default values.
*/
private ModuleDetailsImpl()
{
aliases = new ArrayList<String>(0);
repoVersionMin = new VersionNumber("0.0.0");
repoVersionMax = new VersionNumber("999.999.999");
this.installState = ModuleInstallState.UNKNOWN;
}
/**
* Creates the instance from a set of properties. All the property values are trimmed
* and empty string values are removed from the set. In other words, zero length or
* whitespace strings are not supported.
*
* @param properties the set of properties * @param properties the set of properties
*/ */
public ModuleDetailsImpl(Properties properties) public ModuleDetailsImpl(Properties properties)
{ {
// Set defaults
this();
// Copy the properties so they don't get modified
Properties trimmedProperties = new Properties();
// Trim all the property values
for (Map.Entry entry : properties.entrySet())
{
String key = (String) entry.getKey();
String value = (String) entry.getValue();
if (value == null)
{
// Don't copy nulls over
continue;
}
String trimmedValue = value.trim();
if (trimmedValue.length() == 0)
{
// Don't copy empty strings over
continue;
}
// It is a real value
trimmedProperties.setProperty(key, trimmedValue);
}
// Check that the required properties are present // Check that the required properties are present
List<String> missingProperties = new ArrayList<String>(1); List<String> missingProperties = new ArrayList<String>(1);
// ID // ID
id = properties.getProperty(PROP_ID); id = trimmedProperties.getProperty(PROP_ID);
if (id == null) { missingProperties.add(PROP_ID); } if (id == null)
{
missingProperties.add(PROP_ID);
}
// ALIASES
String aliasesStr = trimmedProperties.getProperty(PROP_ALIASES);
if (aliasesStr != null)
{
StringTokenizer st = new StringTokenizer(aliasesStr, ",");
while (st.hasMoreTokens())
{
String alias = st.nextToken().trim();
if (alias.length() == 0)
{
continue;
}
aliases.add(alias);
}
}
// VERSION // VERSION
if (properties.getProperty(PROP_VERSION) == null) if (trimmedProperties.getProperty(PROP_VERSION) == null)
{ {
missingProperties.add(PROP_VERSION); missingProperties.add(PROP_VERSION);
} }
else else
{ {
version = new VersionNumber(properties.getProperty(PROP_VERSION)); version = new VersionNumber(trimmedProperties.getProperty(PROP_VERSION));
} }
// TITLE // TITLE
title = properties.getProperty(PROP_TITLE); title = trimmedProperties.getProperty(PROP_TITLE);
if (title == null) { missingProperties.add(PROP_TITLE); } if (title == null) { missingProperties.add(PROP_TITLE); }
// DESCRIPTION // DESCRIPTION
description = properties.getProperty(PROP_DESCRIPTION); description = trimmedProperties.getProperty(PROP_DESCRIPTION);
if (description == null) { missingProperties.add(PROP_DESCRIPTION); } if (description == null) { missingProperties.add(PROP_DESCRIPTION); }
// REPO MIN // REPO MIN
if (properties.getProperty(PROP_REPO_VERSION_MIN) == null) if (trimmedProperties.getProperty(PROP_REPO_VERSION_MIN) != null)
{ {
repoVersionMin = new VersionNumber("0.0.0"); repoVersionMin = new VersionNumber(trimmedProperties.getProperty(PROP_REPO_VERSION_MIN));
}
else
{
repoVersionMin = new VersionNumber(properties.getProperty(PROP_REPO_VERSION_MIN));
} }
// REPO MAX // REPO MAX
if (properties.getProperty(PROP_REPO_VERSION_MAX) == null) if (trimmedProperties.getProperty(PROP_REPO_VERSION_MAX) != null)
{ {
repoVersionMax = new VersionNumber("999.999.999"); repoVersionMax = new VersionNumber(trimmedProperties.getProperty(PROP_REPO_VERSION_MAX));
}
else
{
repoVersionMax = new VersionNumber(properties.getProperty(PROP_REPO_VERSION_MAX));
} }
// INSTALL DATE // INSTALL DATE
if (properties.getProperty(PROP_INSTALL_DATE) != null) if (trimmedProperties.getProperty(PROP_INSTALL_DATE) != null)
{ {
String installDateStr = properties.getProperty(PROP_INSTALL_DATE); String installDateStr = trimmedProperties.getProperty(PROP_INSTALL_DATE);
try try
{ {
installDate = ISO8601DateFormat.parse(installDateStr); installDate = ISO8601DateFormat.parse(installDateStr);
@@ -112,6 +164,19 @@ public class ModuleDetailsImpl implements ModuleDetails
throw new AlfrescoRuntimeException("Unable to parse install date: " + installDateStr, e); throw new AlfrescoRuntimeException("Unable to parse install date: " + installDateStr, e);
} }
} }
// INSTALL STATE
if (trimmedProperties.getProperty(PROP_INSTALL_STATE) != null)
{
String installStateStr = trimmedProperties.getProperty(PROP_INSTALL_STATE);
try
{
installState = ModuleInstallState.valueOf(installStateStr);
}
catch (Throwable e)
{
throw new AlfrescoRuntimeException("Unable to parse install state: " + installStateStr, e);
}
}
// Check // Check
if (missingProperties.size() > 0) if (missingProperties.size() > 0)
{ {
@@ -124,9 +189,11 @@ public class ModuleDetailsImpl implements ModuleDetails
" Min repo version: " + repoVersionMin + "\n" + " Min repo version: " + repoVersionMin + "\n" +
" Max repo version: " + repoVersionMax); " Max repo version: " + repoVersionMax);
} }
if (id.matches(INVALID_ID_REGEX))
// Set other defaults {
installState = ModuleInstallState.INSTALLED; throw new AlfrescoRuntimeException(
"The module ID '" + id + "' is invalid. It may consist of valid characters, numbers, '.', '_' and '-'");
}
} }
/** /**
@@ -137,6 +204,9 @@ public class ModuleDetailsImpl implements ModuleDetails
*/ */
public ModuleDetailsImpl(String id, VersionNumber versionNumber, String title, String description) public ModuleDetailsImpl(String id, VersionNumber versionNumber, String title, String description)
{ {
// Set defaults
this();
this.id = id; this.id = id;
this.version = versionNumber; this.version = versionNumber;
this.title = title; this.title = title;
@@ -170,6 +240,21 @@ public class ModuleDetailsImpl implements ModuleDetails
String installStateStr = installState.toString(); String installStateStr = installState.toString();
properties.setProperty(PROP_INSTALL_STATE, installStateStr); properties.setProperty(PROP_INSTALL_STATE, installStateStr);
} }
if (aliases.size() > 0)
{
StringBuilder sb = new StringBuilder();
boolean first = true;
for (String oldId : aliases)
{
if (!first)
{
sb.append(", ");
}
sb.append(oldId);
first = false;
}
properties.setProperty(PROP_ALIASES, sb.toString());
}
// Done // Done
return properties; return properties;
} }
@@ -185,6 +270,11 @@ public class ModuleDetailsImpl implements ModuleDetails
return id; return id;
} }
public List<String> getAliases()
{
return aliases;
}
public VersionNumber getVersion() public VersionNumber getVersion()
{ {
return version; return version;

View File

@@ -0,0 +1,108 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.repo.module;
import java.util.Properties;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.service.cmr.module.ModuleDetails;
import org.alfresco.service.cmr.module.ModuleInstallState;
import org.alfresco.util.VersionNumber;
import junit.framework.TestCase;
/**
* @see org.alfresco.repo.module.ModuleDetailsImpl
*
* @author Derek Hulley
*/
public class ModuleDetailsImplTest extends TestCase
{
private Properties defaultProperties;
@Override
protected void setUp() throws Exception
{
defaultProperties = new Properties();
defaultProperties.setProperty(ModuleDetails.PROP_ID, "org.alfresco.module.Test");
defaultProperties.setProperty(ModuleDetails.PROP_ALIASES, "test, Test");
defaultProperties.setProperty(ModuleDetails.PROP_TITLE, "Test");
defaultProperties.setProperty(ModuleDetails.PROP_DESCRIPTION, "Test description");
defaultProperties.setProperty(ModuleDetails.PROP_VERSION, "1.0.0");
defaultProperties.setProperty(ModuleDetails.PROP_REPO_VERSION_MIN, new VersionNumber("1.2").toString());
defaultProperties.setProperty(ModuleDetails.PROP_REPO_VERSION_MAX, new VersionNumber("1.4.3").toString());
defaultProperties.setProperty(ModuleDetails.PROP_INSTALL_STATE, ModuleInstallState.INSTALLED.toString());
}
@SuppressWarnings("unused")
public void testDefaults()
{
ModuleDetails details = new ModuleDetailsImpl(defaultProperties);
}
public void testWriteAndReadProperties()
{
ModuleDetails details = new ModuleDetailsImpl(defaultProperties);
// convert back to properties
Properties processedProperties = details.getProperties();
assertEquals("The number of properties changed", defaultProperties.size(), processedProperties.size());
assertEquals("The properties are different", defaultProperties, processedProperties);
}
public void testTrimming() throws Exception
{
defaultProperties.setProperty(ModuleDetails.PROP_INSTALL_STATE, " ");
ModuleDetails details = new ModuleDetailsImpl(defaultProperties);
assertEquals("Expected the install state to be UNKNOWN", ModuleInstallState.UNKNOWN, details.getInstallState());
}
public void testInvalidIds() throws Exception
{
String[] invalidIds = new String[] {"", " ", "$", "module$Test", "module.Test$", "org alfresco module Test"};
for (String invalidId : invalidIds)
{
try
{
defaultProperties.setProperty(ModuleDetails.PROP_ID, invalidId);
new ModuleDetailsImpl(defaultProperties);
fail("Invalid ID not detected: " + invalidId);
}
catch (AlfrescoRuntimeException e)
{
// Expected
}
}
}
public void testValidIds() throws Exception
{
String[] validIds = new String[] {"abc123", " abc123 ", "a-b-c", "a.b.c", "a_b_c", "A.1.2.3"};
for (String validId : validIds)
{
defaultProperties.setProperty(ModuleDetails.PROP_ID, validId);
new ModuleDetailsImpl(defaultProperties);
}
}
}

View File

@@ -74,7 +74,6 @@ public class ModuleServiceImpl implements ModuleService
private static Log logger = LogFactory.getLog(ModuleServiceImpl.class); private static Log logger = LogFactory.getLog(ModuleServiceImpl.class);
private ServiceRegistry serviceRegistry; private ServiceRegistry serviceRegistry;
private DescriptorService descriptorService;
private AuthenticationComponent authenticationComponent; private AuthenticationComponent authenticationComponent;
private ModuleComponentHelper moduleComponentHelper; private ModuleComponentHelper moduleComponentHelper;
/** A cache of module details by module ID */ /** A cache of module details by module ID */
@@ -95,7 +94,6 @@ public class ModuleServiceImpl implements ModuleService
public void setDescriptorService(DescriptorService descriptorService) public void setDescriptorService(DescriptorService descriptorService)
{ {
this.descriptorService = descriptorService;
this.moduleComponentHelper.setDescriptorService(descriptorService); this.moduleComponentHelper.setDescriptorService(descriptorService);
} }

View File

@@ -148,9 +148,17 @@ public class InstalledFiles
* *
* @return the file location * @return the file location
*/ */
private String getFileLocation() public String getFileLocation()
{ {
return this.warLocation + ModuleManagementTool.MODULE_DIR + "/" + this.moduleId + "/modifications.install"; return this.warLocation + getFilePathInWar();
}
/**
* @return Returns the path of the install file within the WAR
*/
public String getFilePathInWar()
{
return ModuleManagementTool.MODULE_DIR + "/" + this.moduleId + "/modifications.install";
} }
/** /**

View File

@@ -75,7 +75,7 @@ public class ModuleDetailsHelper
try try
{ {
File file = new File(location, ModuleManagementTool.DETECTOR_AMP_AND_WAR); File file = new File(location, ModuleManagementTool.DETECTOR_AMP_AND_WAR);
if (file.exists() == true) if (file.exists())
{ {
InputStream is = new FileInputStream(file); InputStream is = new FileInputStream(file);
result = createModuleDetailsFromPropertiesStream(is); result = createModuleDetailsFromPropertiesStream(is);
@@ -102,6 +102,19 @@ public class ModuleDetailsHelper
return ModuleDetailsHelper.createModuleDetailsFromPropertyLocation(modulePropertiesFileLocation); return ModuleDetailsHelper.createModuleDetailsFromPropertyLocation(modulePropertiesFileLocation);
} }
/**
* @param warLocation the location of the WAR file
* @param moduleId the module ID within the WAR
* @return Returns a file handle to the module properties file within the given WAR.
* The file may or may not exist.
*/
public static File getModuleDetailsFileFromWarAndId(String warLocation, String moduleId)
{
String location = ModuleDetailsHelper.getModulePropertiesFileLocation(warLocation, moduleId);
File file = new File(location, ModuleManagementTool.DETECTOR_AMP_AND_WAR);
return file;
}
/** /**
* Gets the file location * Gets the file location
* *
@@ -109,9 +122,18 @@ public class ModuleDetailsHelper
* @param moduleId the module id * @param moduleId the module id
* @return the file location * @return the file location
*/ */
private static String getModulePropertiesFileLocation(String warLocation, String moduleId) public static String getModulePropertiesFileLocation(String warLocation, String moduleId)
{ {
return warLocation + ModuleManagementTool.MODULE_DIR + "/" + moduleId + "/" + "module.properties"; return warLocation + getModulePropertiesFilePathInWar(moduleId);
}
/**
* @param moduleId the module ID
* @return Returns the path of the module file within a WAR
*/
public static String getModulePropertiesFilePathInWar(String moduleId)
{
return ModuleManagementTool.MODULE_DIR + "/" + moduleId + "/" + "module.properties";
} }
/** /**

View File

@@ -31,6 +31,7 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.Date; import java.util.Date;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
@@ -229,7 +230,7 @@ public class ModuleManagementTool
backUpDir.mkdir(); backUpDir.mkdir();
} }
// Make a backup of the war we are oging to modify // Make a backup of the war we are going to modify
if (backupWAR == true) if (backupWAR == true)
{ {
java.io.File warFile = new java.io.File(warFileLocation); java.io.File warFile = new java.io.File(warFileLocation);
@@ -255,8 +256,28 @@ public class ModuleManagementTool
String installingId = installingModuleDetails.getId(); String installingId = installingModuleDetails.getId();
VersionNumber installingVersion = installingModuleDetails.getVersion(); VersionNumber installingVersion = installingModuleDetails.getVersion();
// Get the detail of the installed module // Try to find an installed module by the ID
ModuleDetails installedModuleDetails = ModuleDetailsHelper.createModuleDetailsFromWarAndId(warFileLocation, installingModuleDetails.getId()); ModuleDetails installedModuleDetails = ModuleDetailsHelper.createModuleDetailsFromWarAndId(warFileLocation, installingId);
if (installedModuleDetails == null)
{
// It might be there as one of the aliases
List<String> installingAliases = installingModuleDetails.getAliases();
for (String installingAlias : installingAliases)
{
ModuleDetails installedAliasModuleDetails = ModuleDetailsHelper.createModuleDetailsFromWarAndId(warFileLocation, installingAlias);
if (installedAliasModuleDetails == null)
{
// There is nothing by that alias
continue;
}
// We found an alias and will treat it as the same module
installedModuleDetails = installedAliasModuleDetails;
outputMessage("Module '" + installingAlias + "' is installed and is an alias of '" + installingId + "'");
break;
}
}
// Now clean up the old instance
if (installedModuleDetails != null) if (installedModuleDetails != null)
{ {
String installedId = installedModuleDetails.getId(); String installedId = installedModuleDetails.getId();
@@ -453,6 +474,12 @@ public class ModuleManagementTool
outputMessage("Recovering file '" + update.getKey() + "' from backup '" + update.getValue() + "'", true); outputMessage("Recovering file '" + update.getKey() + "' from backup '" + update.getValue() + "'", true);
} }
// Now remove the installed files list
String installedFilesPathInWar = installedFiles.getFilePathInWar();
removeFile(warFileLocation, installedFilesPathInWar, preview);
// Remove the module properties
String modulePropertiesFileLocationInWar = ModuleDetailsHelper.getModulePropertiesFilePathInWar(moduleId);
removeFile(warFileLocation, modulePropertiesFileLocationInWar, preview);
} }
/** /**
@@ -478,7 +505,7 @@ public class ModuleManagementTool
outputMessage("The file '" + filePath + "' was expected for removal but was not present in the war", true); outputMessage("The file '" + filePath + "' was expected for removal but was not present in the war", true);
} }
} }
/** /**
* Copies a file from the AMP location to the correct location in the WAR, interating on directories where appropraite. * Copies a file from the AMP location to the correct location in the WAR, interating on directories where appropraite.
* *

View File

@@ -1,4 +1,4 @@
# The default AEP => WAR file mappings # The default AMP => WAR file mappings
/config=/WEB-INF/classes /config=/WEB-INF/classes
/lib=/WEB-INF/lib /lib=/WEB-INF/lib
/licenses=/WEB-INF/licenses /licenses=/WEB-INF/licenses

View File

@@ -25,6 +25,7 @@
package org.alfresco.service.cmr.module; package org.alfresco.service.cmr.module;
import java.util.Date; import java.util.Date;
import java.util.List;
import java.util.Properties; import java.util.Properties;
import org.alfresco.util.VersionNumber; import org.alfresco.util.VersionNumber;
@@ -38,6 +39,7 @@ import org.alfresco.util.VersionNumber;
public interface ModuleDetails public interface ModuleDetails
{ {
static final String PROP_ID = "module.id"; static final String PROP_ID = "module.id";
static final String PROP_ALIASES = "module.aliases";
static final String PROP_VERSION = "module.version"; static final String PROP_VERSION = "module.version";
static final String PROP_TITLE = "module.title"; static final String PROP_TITLE = "module.title";
static final String PROP_DESCRIPTION = "module.description"; static final String PROP_DESCRIPTION = "module.description";
@@ -46,6 +48,8 @@ public interface ModuleDetails
static final String PROP_INSTALL_DATE = "module.installDate"; static final String PROP_INSTALL_DATE = "module.installDate";
static final String PROP_INSTALL_STATE = "module.installState"; static final String PROP_INSTALL_STATE = "module.installState";
static final String INVALID_ID_REGEX = ".*[^\\w.-].*";
/** /**
* Get all defined properties. * Get all defined properties.
* *
@@ -60,6 +64,11 @@ public interface ModuleDetails
*/ */
String getId(); String getId();
/**
* @return Returns a list of IDs by which this module may once have been known
*/
List<String> getAliases();
/** /**
* Get the version number of the module * Get the version number of the module
* *

View File

@@ -32,7 +32,7 @@ package org.alfresco.service.cmr.module;
public enum ModuleInstallState public enum ModuleInstallState
{ {
/** The state of the module is unknown */ /** The state of the module is unknown */
UKNOWN, UNKNOWN,
/** The module is installed */ /** The module is installed */
INSTALLED, INSTALLED,
/** The module is disabled */ /** The module is disabled */