diff --git a/pom.xml b/pom.xml index 6fe55e9009..fc93998139 100644 --- a/pom.xml +++ b/pom.xml @@ -224,6 +224,11 @@ subethasmtp 3.1.6 + + org.apache.maven + maven-artifact + 3.2.1 + de.schlichtherle.truezip truezip-driver-zip diff --git a/source/java/org/alfresco/repo/module/AbstractModuleComponent.java b/source/java/org/alfresco/repo/module/AbstractModuleComponent.java index b6a40cb038..0bd0c887d3 100644 --- a/source/java/org/alfresco/repo/module/AbstractModuleComponent.java +++ b/source/java/org/alfresco/repo/module/AbstractModuleComponent.java @@ -24,15 +24,14 @@ import java.util.List; import java.util.Map; import org.alfresco.error.AlfrescoRuntimeException; -import org.springframework.extensions.surf.util.I18NUtil; import org.alfresco.repo.security.authentication.AuthenticationComponent; import org.alfresco.repo.tenant.TenantAdminService; import org.alfresco.service.ServiceRegistry; import org.alfresco.service.cmr.module.ModuleService; import org.alfresco.util.EqualsHelper; import org.alfresco.util.PropertyCheck; -import org.alfresco.util.VersionNumber; import org.springframework.beans.factory.BeanNameAware; +import org.springframework.extensions.surf.util.I18NUtil; /** * Implementation of a {@link org.alfresco.repo.module.ModuleComponent} to provide @@ -58,9 +57,9 @@ public abstract class AbstractModuleComponent implements ModuleComponent, BeanNa private String moduleId; private String name; private String description; - private VersionNumber sinceVersion; - private VersionNumber appliesFromVersion; - private VersionNumber appliesToVersion; + private ModuleVersionNumber sinceVersion; + private ModuleVersionNumber appliesFromVersion; + private ModuleVersionNumber appliesToVersion; private List dependsOn; /** Defaults to true */ private boolean executeOnceOnly; @@ -68,9 +67,9 @@ public abstract class AbstractModuleComponent implements ModuleComponent, BeanNa public AbstractModuleComponent() { - sinceVersion = VersionNumber.VERSION_ZERO; - appliesFromVersion = VersionNumber.VERSION_ZERO; - appliesToVersion = VersionNumber.VERSION_BIG; + sinceVersion = ModuleVersionNumber.VERSION_ZERO; + appliesFromVersion = ModuleVersionNumber.VERSION_ZERO; + appliesToVersion = ModuleVersionNumber.VERSION_BIG; dependsOn = new ArrayList(0); executeOnceOnly = true; executed = new HashMap(1); @@ -226,7 +225,7 @@ public abstract class AbstractModuleComponent implements ModuleComponent, BeanNa /** * {@inheritDoc} */ - public VersionNumber getSinceVersionNumber() + public ModuleVersionNumber getSinceVersionNumber() { return sinceVersion; } @@ -236,13 +235,13 @@ public abstract class AbstractModuleComponent implements ModuleComponent, BeanNa */ public void setSinceVersion(String version) { - this.sinceVersion = new VersionNumber(version); + this.sinceVersion = new ModuleVersionNumber(version); } /** * {@inheritDoc} */ - public VersionNumber getAppliesFromVersionNumber() + public ModuleVersionNumber getAppliesFromVersionNumber() { return appliesFromVersion; } @@ -253,13 +252,13 @@ public abstract class AbstractModuleComponent implements ModuleComponent, BeanNa */ public void setAppliesFromVersion(String version) { - this.appliesFromVersion = new VersionNumber(version); + this.appliesFromVersion = new ModuleVersionNumber(version); } /** * {@inheritDoc} */ - public VersionNumber getAppliesToVersionNumber() + public ModuleVersionNumber getAppliesToVersionNumber() { return appliesToVersion; } @@ -270,7 +269,7 @@ public abstract class AbstractModuleComponent implements ModuleComponent, BeanNa */ public void setAppliesToVersion(String version) { - this.appliesToVersion = new VersionNumber(version); + this.appliesToVersion = new ModuleVersionNumber(version); } /** diff --git a/source/java/org/alfresco/repo/module/ModuleComponent.java b/source/java/org/alfresco/repo/module/ModuleComponent.java index 9920980cca..fc14fb0c09 100644 --- a/source/java/org/alfresco/repo/module/ModuleComponent.java +++ b/source/java/org/alfresco/repo/module/ModuleComponent.java @@ -58,17 +58,17 @@ public interface ModuleComponent /** * @return Returns the version number of the module for which this component was introduced. */ - VersionNumber getSinceVersionNumber(); + ModuleVersionNumber getSinceVersionNumber(); /** * @return Returns the smallest version number of the module to which this component applies. */ - VersionNumber getAppliesFromVersionNumber(); + ModuleVersionNumber getAppliesFromVersionNumber(); /** * @return Returns the largest version number of the module to which this component applies. */ - VersionNumber getAppliesToVersionNumber(); + ModuleVersionNumber getAppliesToVersionNumber(); /** * A list of module components that must be executed prior to this instance. diff --git a/source/java/org/alfresco/repo/module/ModuleComponentHelper.java b/source/java/org/alfresco/repo/module/ModuleComponentHelper.java index c32e427baa..5cd35047bb 100644 --- a/source/java/org/alfresco/repo/module/ModuleComponentHelper.java +++ b/source/java/org/alfresco/repo/module/ModuleComponentHelper.java @@ -18,6 +18,7 @@ */ package org.alfresco.repo.module; +import java.io.Serializable; import java.util.Collection; import java.util.Collections; import java.util.Date; @@ -28,9 +29,9 @@ import java.util.Map; import java.util.Set; import org.alfresco.error.AlfrescoRuntimeException; -import org.springframework.extensions.surf.util.I18NUtil; import org.alfresco.repo.admin.registry.RegistryKey; import org.alfresco.repo.admin.registry.RegistryService; +import org.alfresco.repo.module.tool.ModuleManagementToolException; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; import org.alfresco.repo.tenant.Tenant; @@ -49,6 +50,7 @@ import org.alfresco.util.PropertyCheck; import org.alfresco.util.VersionNumber; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.springframework.extensions.surf.util.I18NUtil; /** * Helper class to split up some of the code for managing module components. This class handles @@ -421,13 +423,13 @@ public class ModuleComponentHelper * @param moduleId * @return */ - VersionNumber getVersion(String moduleId) + ModuleVersionNumber getVersion(String moduleId) { RegistryKey moduleKeyCurrentVersion = new RegistryKey( ModuleComponentHelper.URI_MODULES_1_0, REGISTRY_PATH_MODULES, moduleId, REGISTRY_PROPERTY_CURRENT_VERSION); - VersionNumber versionCurrent = (VersionNumber) registryService.getProperty(moduleKeyCurrentVersion); - return versionCurrent; + Serializable versionCurrent = registryService.getProperty(moduleKeyCurrentVersion); + return getModuleVersionNumber(versionCurrent); } /** @@ -456,7 +458,7 @@ public class ModuleComponentHelper { // Get the specifics of the missing module - VersionNumber versionCurrent = getVersion(moduleId); + ModuleVersionNumber versionCurrent = getVersion(moduleId); // The module is missing, so warn loggerService.warn(I18NUtil.getMessage(MSG_MISSING, moduleId, versionCurrent)); } @@ -527,7 +529,7 @@ public class ModuleComponentHelper private void startModule(ModuleDetails module, Set startedModules, Set executedComponents) { String moduleId = module.getId(); - VersionNumber moduleNewVersion = module.getVersion(); + ModuleVersionNumber moduleNewVersion = module.getVersion(); // Double check whether we have done this module already if (startedModules.contains(moduleId)) @@ -596,8 +598,8 @@ public class ModuleComponentHelper RegistryKey moduleKeyCurrentVersion = new RegistryKey( ModuleComponentHelper.URI_MODULES_1_0, REGISTRY_PATH_MODULES, moduleId, REGISTRY_PROPERTY_CURRENT_VERSION); - VersionNumber moduleInstallVersion = (VersionNumber) registryService.getProperty(moduleKeyInstalledVersion); - VersionNumber moduleCurrentVersion = (VersionNumber) registryService.getProperty(moduleKeyCurrentVersion); + Serializable moduleInstallVersion = registryService.getProperty(moduleKeyInstalledVersion); + Serializable moduleCurrentVersion = registryService.getProperty(moduleKeyCurrentVersion); String msg = null; if (moduleCurrentVersion == null) // No previous record of it { @@ -609,21 +611,23 @@ public class ModuleComponentHelper } else // It is an upgrade or is the same { + ModuleVersionNumber currentModuleVersion = getModuleVersionNumber(moduleCurrentVersion); + // Check that we have an installed version if (moduleInstallVersion == null) { // A current version, but no installed version logger.warn(I18NUtil.getMessage(WARN_NO_INSTALL_VERSION, moduleId, moduleCurrentVersion)); // Record the install version - registryService.addProperty(moduleKeyInstalledVersion, moduleCurrentVersion); + registryService.addProperty(moduleKeyInstalledVersion, currentModuleVersion); moduleInstallVersion = moduleCurrentVersion; } - if (moduleCurrentVersion.compareTo(moduleNewVersion) == 0) // The current version is the same + if (currentModuleVersion.compareTo(moduleNewVersion) == 0) // The current version is the same { msg = I18NUtil.getMessage(MSG_STARTING, moduleId, moduleNewVersion); } - else if (moduleCurrentVersion.compareTo(moduleNewVersion) > 0) // Downgrading not supported + else if (currentModuleVersion.compareTo(moduleNewVersion) > 0) // Downgrading not supported { throw AlfrescoRuntimeException.create(ERR_NO_DOWNGRADE, moduleId, moduleCurrentVersion, moduleNewVersion); } @@ -652,12 +656,20 @@ public class ModuleComponentHelper } } + protected ModuleVersionNumber getModuleVersionNumber(Serializable moduleVersion) + { + if (moduleVersion instanceof ModuleVersionNumber) return (ModuleVersionNumber) moduleVersion; + if (moduleVersion instanceof VersionNumber) return new ModuleVersionNumber((VersionNumber)moduleVersion); + if (moduleVersion instanceof String) return new ModuleVersionNumber((String)moduleVersion); + throw new ModuleManagementToolException("Invalid moduleVersion"); + } + /** * Execute the component, respecting dependencies. */ private void executeComponent( String moduleId, - VersionNumber currentVersion, + ModuleVersionNumber currentVersion, ModuleComponent component, Set executedComponents) { @@ -676,8 +688,8 @@ public class ModuleComponentHelper executedComponents.add(component); // Check the version applicability - VersionNumber minVersion = component.getAppliesFromVersionNumber(); - VersionNumber maxVersion = component.getAppliesToVersionNumber(); + ModuleVersionNumber minVersion = component.getAppliesFromVersionNumber(); + ModuleVersionNumber maxVersion = component.getAppliesToVersionNumber(); if (currentVersion.compareTo(minVersion) < 0 || currentVersion.compareTo(maxVersion) > 0) { // It is out of the allowable range for execution so we just ignore it diff --git a/source/java/org/alfresco/repo/module/ModuleDetailsImpl.java b/source/java/org/alfresco/repo/module/ModuleDetailsImpl.java index 8ffb999dc1..62edc0cda1 100644 --- a/source/java/org/alfresco/repo/module/ModuleDetailsImpl.java +++ b/source/java/org/alfresco/repo/module/ModuleDetailsImpl.java @@ -49,7 +49,7 @@ public class ModuleDetailsImpl implements ModuleDetails private String id; private List aliases; - private VersionNumber version; + private ModuleVersionNumber version; private String title; private String description; private List editions; @@ -77,6 +77,7 @@ public class ModuleDetailsImpl implements ModuleDetails * whitespace strings are not supported. * * @param properties the set of properties + * @Throws AlfrescoRuntimeException if unable to parse values */ public ModuleDetailsImpl(Properties properties) { @@ -136,11 +137,11 @@ public class ModuleDetailsImpl implements ModuleDetails { try { - version = new VersionNumber(trimmedProperties.getProperty(PROP_VERSION)); + version = new ModuleVersionNumber(trimmedProperties.getProperty(PROP_VERSION)); } catch (Throwable e) { - throw new AlfrescoRuntimeException("Unable to parse version information: " + trimmedProperties.getProperty(PROP_VERSION), e); + throw new AlfrescoRuntimeException("Unable to parse version information: " + PROP_VERSION + ", " + trimmedProperties.getProperty(PROP_VERSION), e); } } // TITLE @@ -152,12 +153,26 @@ public class ModuleDetailsImpl implements ModuleDetails // REPO MIN if (trimmedProperties.getProperty(PROP_REPO_VERSION_MIN) != null) { - repoVersionMin = new VersionNumber(trimmedProperties.getProperty(PROP_REPO_VERSION_MIN)); + try + { + repoVersionMin = new VersionNumber(trimmedProperties.getProperty(PROP_REPO_VERSION_MIN)); + } + catch (Throwable t) + { + throw new AlfrescoRuntimeException("Unable to parse repo version min: " + PROP_REPO_VERSION_MIN + ", " + repoVersionMin, t); + } } // REPO MAX if (trimmedProperties.getProperty(PROP_REPO_VERSION_MAX) != null) { - repoVersionMax = new VersionNumber(trimmedProperties.getProperty(PROP_REPO_VERSION_MAX)); + try + { + repoVersionMax = new VersionNumber(trimmedProperties.getProperty(PROP_REPO_VERSION_MAX)); + } + catch (Throwable t) + { + throw new AlfrescoRuntimeException("Unable to parse repo version max: " + PROP_REPO_VERSION_MAX + ", " + repoVersionMax, t); + } } // DEPENDENCIES this.dependencies = extractDependencies(trimmedProperties); @@ -174,7 +189,7 @@ public class ModuleDetailsImpl implements ModuleDetails } catch (Throwable e) { - throw new AlfrescoRuntimeException("Unable to parse install date: " + installDateStr, e); + throw new AlfrescoRuntimeException("Unable to parse install date: " + PROP_INSTALL_DATE + ", " + installDateStr, e); } } // INSTALL STATE @@ -187,7 +202,7 @@ public class ModuleDetailsImpl implements ModuleDetails } catch (Throwable e) { - throw new AlfrescoRuntimeException("Unable to parse install state: " + installStateStr, e); + throw new AlfrescoRuntimeException("Unable to parse install state: " + PROP_INSTALL_STATE +", " + installStateStr, e); } } // Check @@ -215,7 +230,7 @@ public class ModuleDetailsImpl implements ModuleDetails * @param title title * @param description description */ - public ModuleDetailsImpl(String id, VersionNumber versionNumber, String title, String description) + public ModuleDetailsImpl(String id, ModuleVersionNumber versionNumber, String title, String description) { // Set defaults this(); @@ -345,7 +360,7 @@ public class ModuleDetailsImpl implements ModuleDetails return aliases; } - public VersionNumber getVersion() + public ModuleVersionNumber getVersion() { return version; } @@ -467,7 +482,7 @@ public class ModuleDetailsImpl implements ModuleDetails private String dependencyId; private String versionStr; - private List> versionRanges; + private List> versionRanges; private ModuleDependencyImpl(String dependencyId, String versionStr) { @@ -491,9 +506,9 @@ public class ModuleDetailsImpl implements ModuleDetails return sb.toString(); } - private static List> buildVersionRanges(String versionStr) + private static List> buildVersionRanges(String versionStr) { - List> versionRanges = new ArrayList>(1); + List> versionRanges = new ArrayList>(1); StringTokenizer rangesTokenizer = new StringTokenizer(versionStr, ","); while (rangesTokenizer.hasMoreTokens()) { @@ -513,8 +528,8 @@ public class ModuleDetailsImpl implements ModuleDetails } // The range must have at least one version in it StringTokenizer rangeTokenizer = new StringTokenizer(range, "-", false); - VersionNumber versionLower = null; - VersionNumber versionUpper = null; + ModuleVersionNumber versionLower = null; + ModuleVersionNumber versionUpper = null; while (rangeTokenizer.hasMoreTokens()) { String version = rangeTokenizer.nextToken(); @@ -524,12 +539,12 @@ public class ModuleDetailsImpl implements ModuleDetails if (version.equals("*")) { // Unbounded lower version - versionLower = VersionNumber.VERSION_ZERO; + versionLower = ModuleVersionNumber.VERSION_ZERO; } else { // Explicit lower bound - versionLower = new VersionNumber(version); + versionLower = new ModuleVersionNumber(version); } } else if (versionUpper == null) @@ -537,12 +552,12 @@ public class ModuleDetailsImpl implements ModuleDetails if (version.equals("*")) { // Unbounded upper version - versionUpper = VersionNumber.VERSION_BIG; + versionUpper = ModuleVersionNumber.VERSION_BIG; } else { // Explicit upper bound - versionUpper = new VersionNumber(version); + versionUpper = new ModuleVersionNumber(version); } } } @@ -565,7 +580,7 @@ public class ModuleDetailsImpl implements ModuleDetails versionLower = versionUpper; } // Create the range pair - Pair rangePair = new Pair(versionLower, versionUpper); + Pair rangePair = new Pair(versionLower, versionUpper); versionRanges.add(rangePair); } return versionRanges; @@ -594,12 +609,12 @@ public class ModuleDetailsImpl implements ModuleDetails return false; } // Check the version number - VersionNumber checkVersion = moduleDetails.getVersion(); + ModuleVersionNumber checkVersion = moduleDetails.getVersion(); boolean matched = false; - for (Pair versionRange : versionRanges) + for (Pair versionRange : versionRanges) { - VersionNumber versionLower = versionRange.getFirst(); - VersionNumber versionUpper = versionRange.getSecond(); + ModuleVersionNumber versionLower = versionRange.getFirst(); + ModuleVersionNumber versionUpper = versionRange.getSecond(); if (checkVersion.compareTo(versionLower) < 0) { // The version is too low diff --git a/source/java/org/alfresco/repo/module/ModuleServiceImpl.java b/source/java/org/alfresco/repo/module/ModuleServiceImpl.java index 46b11d49fc..0c54f7ee1f 100644 --- a/source/java/org/alfresco/repo/module/ModuleServiceImpl.java +++ b/source/java/org/alfresco/repo/module/ModuleServiceImpl.java @@ -196,7 +196,7 @@ public class ModuleServiceImpl implements ApplicationContextAware, ModuleService if (moduleDetails == null) { // Get the specifics of the missing module and add them to the list. - VersionNumber currentVersion = moduleComponentHelper.getVersion(moduleId); + ModuleVersionNumber currentVersion = moduleComponentHelper.getVersion(moduleId); ModuleDetails newModuleDetails = new ModuleDetailsImpl(moduleId, currentVersion, "", ""); diff --git a/source/java/org/alfresco/repo/module/ModuleVersionNumber.java b/source/java/org/alfresco/repo/module/ModuleVersionNumber.java new file mode 100644 index 0000000000..32d698bdb4 --- /dev/null +++ b/source/java/org/alfresco/repo/module/ModuleVersionNumber.java @@ -0,0 +1,94 @@ +package org.alfresco.repo.module; + +import java.io.Externalizable; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; + +import org.alfresco.util.VersionNumber; +import org.apache.maven.artifact.versioning.ComparableVersion; + +/** + * The exising Alfresco VersionNumber can only be numeric. + * ModuleVersionNumber allows string literals in the version number. + * + * It follows maven conventions and actually uses the ComparableVersion class + * from the maven code base. + * + * @author Gethin James + */ + +public class ModuleVersionNumber implements Externalizable +{ + private static final long serialVersionUID = 8594906471270433420L; + + public static final ModuleVersionNumber VERSION_ZERO = new ModuleVersionNumber("0");; + public static final ModuleVersionNumber VERSION_BIG = new ModuleVersionNumber("999.999.999.99"); + + protected ComparableVersion delegate; + + public ModuleVersionNumber() + { + super(); + } + + public ModuleVersionNumber(String versionString) + { + delegate = new ComparableVersion(versionString); + } + + public ModuleVersionNumber(VersionNumber versionCurrent) + { + this(versionCurrent.toString()); + } + + public int compareTo(ModuleVersionNumber installingVersion) + { + return delegate.compareTo(installingVersion.delegate); + } + + @Override + public int hashCode() + { + final int prime = 31; + int result = 1; + result = prime * result + ((this.delegate == null) ? 0 : this.delegate.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) + { + if (this == obj) return true; + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; + ModuleVersionNumber other = (ModuleVersionNumber) obj; + if (this.delegate == null) + { + if (other.delegate != null) return false; + } + else if (!this.delegate.equals(other.delegate)) return false; + return true; + } + + @Override + public String toString() + { + return this.delegate.toString(); + } + + @Override + public void writeExternal(ObjectOutput out) throws IOException + { + out.writeUTF(delegate.toString()); + } + + @Override + public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException + { + String versionString = in.readUTF(); + delegate = new ComparableVersion(versionString); + } + + +} diff --git a/source/java/org/alfresco/repo/module/tool/ModuleDetailsHelper.java b/source/java/org/alfresco/repo/module/tool/ModuleDetailsHelper.java index 3fb5a1c3d6..283976008b 100644 --- a/source/java/org/alfresco/repo/module/tool/ModuleDetailsHelper.java +++ b/source/java/org/alfresco/repo/module/tool/ModuleDetailsHelper.java @@ -75,7 +75,7 @@ public class ModuleDetailsHelper } catch (FileNotFoundException error) { - throw new ModuleManagementToolException("Unable to load module details from property file.", error); + throw new ModuleManagementToolException("Unable to load module details from property file. " + error.getMessage(), error); } try @@ -85,7 +85,7 @@ public class ModuleDetailsHelper catch (IOException exception) { throw new ModuleManagementToolException( - "Unable to load module details from property file.", exception); + "Unable to load module details from property file." + exception.getMessage(), exception); } finally { diff --git a/source/java/org/alfresco/repo/module/tool/ModuleManagementTool.java b/source/java/org/alfresco/repo/module/tool/ModuleManagementTool.java index 93eb9fd9ed..05163f1fc5 100644 --- a/source/java/org/alfresco/repo/module/tool/ModuleManagementTool.java +++ b/source/java/org/alfresco/repo/module/tool/ModuleManagementTool.java @@ -27,6 +27,7 @@ import java.util.Map.Entry; import java.util.Properties; import org.alfresco.error.AlfrescoRuntimeException; +import org.alfresco.repo.module.ModuleVersionNumber; import org.alfresco.service.cmr.module.ModuleDetails; import org.alfresco.service.cmr.module.ModuleInstallState; import org.alfresco.util.VersionNumber; @@ -230,7 +231,7 @@ public class ModuleManagementTool implements LogOutput throw new ModuleManagementToolException("No module.properties file has been found in the installing .amp file '" + ampFileLocation + "'"); } String installingId = installingModuleDetails.getId(); - VersionNumber installingVersion = installingModuleDetails.getVersion(); + ModuleVersionNumber installingVersion = installingModuleDetails.getVersion(); //A series of checks warHelper.checkCompatibleVersion(warFile, installingModuleDetails); @@ -285,6 +286,10 @@ public class ModuleManagementTool implements LogOutput TVFS.umount(); } } + catch (AlfrescoRuntimeException exception) + { + throw new ModuleManagementToolException("An error was encountered during deployment of the AMP into the WAR: " + exception.getMessage(), exception); + } catch (IOException exception) { throw new ModuleManagementToolException("An IO error was encountered during deployment of the AMP into the WAR", exception); @@ -292,13 +297,13 @@ public class ModuleManagementTool implements LogOutput } private void uninstallIfNecessary(String warFileLocation, ModuleDetails installedModuleDetails, boolean preview, - boolean forceInstall, VersionNumber installingVersion) throws IOException + boolean forceInstall, ModuleVersionNumber installingVersion) throws IOException { // Now clean up the old instance if (installedModuleDetails != null) { String installedId = installedModuleDetails.getId(); - VersionNumber installedVersion = installedModuleDetails.getVersion(); + ModuleVersionNumber installedVersion = installedModuleDetails.getVersion(); int compareValue = installedVersion.compareTo(installingVersion); if (compareValue > 0) @@ -655,6 +660,7 @@ public class ModuleManagementTool implements LogOutput * Lists all the currently installed modules in the WAR * * @param warLocation the war location + * @throws ModuleManagementToolException */ public void listModules(String warLocation) { @@ -688,6 +694,10 @@ public class ModuleManagementTool implements LogOutput is = new TFileInputStream(moduleProperties); moduleDetails = ModuleDetailsHelper.createModuleDetailsFromPropertiesStream(is); } + catch (AlfrescoRuntimeException exception) + { + throw new ModuleManagementToolException("Unable to open module properties file '" + moduleProperties.getPath() + "' " + exception.getMessage(), exception); + } catch (IOException exception) { throw new ModuleManagementToolException("Unable to open module properties file '" + moduleProperties.getPath() + "'", exception); diff --git a/source/java/org/alfresco/service/cmr/module/ModuleDetails.java b/source/java/org/alfresco/service/cmr/module/ModuleDetails.java index f7b34993ff..5f4d93c338 100644 --- a/source/java/org/alfresco/service/cmr/module/ModuleDetails.java +++ b/source/java/org/alfresco/service/cmr/module/ModuleDetails.java @@ -24,6 +24,7 @@ import java.util.List; import java.util.Properties; import org.alfresco.api.AlfrescoPublicApi; +import org.alfresco.repo.module.ModuleVersionNumber; import org.alfresco.util.VersionNumber; /** @@ -73,7 +74,7 @@ public interface ModuleDetails extends Serializable * * @return module version number */ - VersionNumber getVersion(); + ModuleVersionNumber getVersion(); /** * Get the title of the module diff --git a/source/test-java/org/alfresco/AllUnitTestsSuite.java b/source/test-java/org/alfresco/AllUnitTestsSuite.java index 1fe2b27b42..50d9a1b65f 100644 --- a/source/test-java/org/alfresco/AllUnitTestsSuite.java +++ b/source/test-java/org/alfresco/AllUnitTestsSuite.java @@ -42,6 +42,7 @@ public class AllUnitTestsSuite extends TestSuite suite.addTest(new JUnit4TestAdapter(org.alfresco.repo.lock.LockUtilsTest.class)); suite.addTest(new JUnit4TestAdapter(org.alfresco.repo.lock.mem.LockStoreImplTest.class)); suite.addTestSuite(org.alfresco.repo.module.ModuleDetailsImplTest.class); + suite.addTestSuite(org.alfresco.repo.module.ModuleVersionNumberTest.class); suite.addTestSuite(org.alfresco.repo.module.tool.ModuleManagementToolTest.class); suite.addTest(new JUnit4TestAdapter(org.alfresco.repo.module.tool.WarHelperImplTest.class)); suite.addTest(new JUnit4TestAdapter(org.alfresco.repo.nodelocator.NodeLocatorServiceImplTest.class)); diff --git a/source/test-java/org/alfresco/repo/module/ModuleComponentHelperTest.java b/source/test-java/org/alfresco/repo/module/ModuleComponentHelperTest.java index 0e1073045a..fd61fa54e8 100644 --- a/source/test-java/org/alfresco/repo/module/ModuleComponentHelperTest.java +++ b/source/test-java/org/alfresco/repo/module/ModuleComponentHelperTest.java @@ -25,6 +25,7 @@ import java.util.List; import java.util.Map; import org.alfresco.repo.admin.registry.RegistryService; +import org.alfresco.repo.module.tool.ModuleManagementToolException; import org.alfresco.repo.tenant.TenantAdminService; import org.alfresco.service.cmr.module.ModuleDetails; import org.alfresco.service.cmr.module.ModuleService; @@ -134,7 +135,7 @@ public class ModuleComponentHelperTest extends BaseAlfrescoTestCase // See that it all starts OK } - private void startComponents(VersionNumber moduleVersion) + private void startComponents(ModuleVersionNumber moduleVersion) { int expectedCount = (Integer) EXECUTION_COUNT_BY_VERSION.get(moduleVersion); // Set the current version number for all modules @@ -149,7 +150,7 @@ public class ModuleComponentHelperTest extends BaseAlfrescoTestCase // tenantCount = tenantDeployerService.getTenants(true).size(); // } // // Check -// assertEquals( +// assertEquals(ModuleVersionNumber // "Incorrent number of executions (version " + moduleVersion + ")", // expectedCount + (expectedCount * tenantCount), // executed); @@ -159,48 +160,68 @@ public class ModuleComponentHelperTest extends BaseAlfrescoTestCase public void testStartComponentsV00() { - VersionNumber moduleVersion = new VersionNumber("0.0"); + ModuleVersionNumber moduleVersion = new ModuleVersionNumber("0.0"); startComponents(moduleVersion); } public void testStartComponentsV05() { - VersionNumber moduleVersion = new VersionNumber("0.5"); + ModuleVersionNumber moduleVersion = new ModuleVersionNumber("0.5"); startComponents(moduleVersion); } public void testStartComponentsV10() { - VersionNumber moduleVersion = new VersionNumber("1.0"); + ModuleVersionNumber moduleVersion = new ModuleVersionNumber("1.0"); startComponents(moduleVersion); } public void testStartComponentsV15() { - VersionNumber moduleVersion = new VersionNumber("1.5"); + ModuleVersionNumber moduleVersion = new ModuleVersionNumber("1.5"); startComponents(moduleVersion); } public void testStartComponentsV30() { - VersionNumber moduleVersion = new VersionNumber("3.0"); + ModuleVersionNumber moduleVersion = new ModuleVersionNumber("3.0"); startComponents(moduleVersion); } public void testStartComponentsV35() { - VersionNumber moduleVersion = new VersionNumber("3.5"); + ModuleVersionNumber moduleVersion = new ModuleVersionNumber("3.5"); startComponents(moduleVersion); } + public void testgetModuleVersionNumber() { + ModuleVersionNumber moduleVersion = new ModuleVersionNumber("3.5"); + VersionNumber versNumber = new VersionNumber("3.5"); + assertEquals(moduleVersion, helper.getModuleVersionNumber(moduleVersion)); + assertEquals(moduleVersion, helper.getModuleVersionNumber(versNumber)); + + try { + helper.getModuleVersionNumber(null); + assertTrue(false); //should never get here + } catch (ModuleManagementToolException e) { + //should get here + } + try { + helper.getModuleVersionNumber("any object"); + assertTrue(false); //should never get here + } catch (ModuleManagementToolException e) { + //should get here + } + assertTrue(true); + } /** * Helper bean to simulate module presences under controlled conditions. */ private class DummyModuleService implements ModuleService { - private VersionNumber currentVersion; + private ModuleVersionNumber currentVersion; /** Set the current version of all the modules */ - public void setCurrentVersion(VersionNumber currentVersion) + public void setCurrentVersion(ModuleVersionNumber currentVersion) { this.currentVersion = currentVersion; } diff --git a/source/test-java/org/alfresco/repo/module/ModuleVersionNumberTest.java b/source/test-java/org/alfresco/repo/module/ModuleVersionNumberTest.java new file mode 100644 index 0000000000..e0d4f00549 --- /dev/null +++ b/source/test-java/org/alfresco/repo/module/ModuleVersionNumberTest.java @@ -0,0 +1,224 @@ + +package org.alfresco.repo.module; + +/* + * Copyright (C) 2005-2014 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * Alfresco 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 3 of the License, or + * (at your option) any later version. + * + * Alfresco 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. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; + +import junit.framework.TestCase; + +/** + * I took the existing @see VersionNumberTest class and added some + * additional tests for ModuleVersionNumber. + * + * @author Gethin James + */ +public class ModuleVersionNumberTest extends TestCase +{ + public void testCreate() + { + ModuleVersionNumber version0 = ModuleVersionNumber.VERSION_ZERO; + assertNotNull(version0); + + ModuleVersionNumber versionBig = ModuleVersionNumber.VERSION_BIG; + assertNotNull(versionBig); + + ModuleVersionNumber version1 = new ModuleVersionNumber("1"); + assertNotNull(version1); + + ModuleVersionNumber version2 = new ModuleVersionNumber("1.2"); + assertNotNull(version2); + + ModuleVersionNumber version3 = new ModuleVersionNumber("1.2.3"); + assertNotNull(version3); + + ModuleVersionNumber versiona = new ModuleVersionNumber("1.2.3a"); + assertNotNull(versiona); + + ModuleVersionNumber versionSnap = new ModuleVersionNumber("1.2.3-SNAPSHOT"); + assertNotNull(versionSnap); + + ModuleVersionNumber versionFinal = new ModuleVersionNumber("1.2.3-final"); + assertNotNull(versionFinal); + + ModuleVersionNumber versionMixed = new ModuleVersionNumber("0.1-incubating-unreleased"); + assertNotNull(versionMixed); + + versionMixed = new ModuleVersionNumber("3.2.6-alfresco-patched"); + assertNotNull(versionMixed); + + versionMixed = new ModuleVersionNumber("0.2-20120518"); + assertNotNull(versionMixed); + + ModuleVersionNumber version1s = new ModuleVersionNumber("4.2.0-SNAPSHOT"); + assertNotNull(version1s); + ModuleVersionNumber version4c = new ModuleVersionNumber("4.2.0-C"); + assertNotNull(version4c); + ModuleVersionNumber version16 = new ModuleVersionNumber("4.0.1.16"); + assertNotNull(version16); + ModuleVersionNumber versionn1 = new ModuleVersionNumber("4.0.16.1.7"); + assertNotNull(versionn1); + ModuleVersionNumber versionn2 = new ModuleVersionNumber("4.0.1.2.8.9"); + assertNotNull(versionn2); + ModuleVersionNumber versionc = new ModuleVersionNumber("4.2.c"); + assertNotNull(versionc); + ModuleVersionNumber versionb = new ModuleVersionNumber("1.0.b"); + assertNotNull(versionb); + ModuleVersionNumber versionsnap = new ModuleVersionNumber("1.0-SNAPSHOT"); + assertNotNull(versionsnap); + } + + public void testEquals() + { + ModuleVersionNumber version0 = new ModuleVersionNumber("1"); + ModuleVersionNumber version1 = new ModuleVersionNumber("1.2"); + ModuleVersionNumber version2 = new ModuleVersionNumber("1.2"); + ModuleVersionNumber version3 = new ModuleVersionNumber("1.2.3"); + ModuleVersionNumber version4 = new ModuleVersionNumber("1.2.3"); + ModuleVersionNumber version5 = new ModuleVersionNumber("1.3.3"); + ModuleVersionNumber version6 = new ModuleVersionNumber("1.0"); + ModuleVersionNumber versiona = new ModuleVersionNumber("1.0.a"); + ModuleVersionNumber versionb = new ModuleVersionNumber("1.0.b"); + ModuleVersionNumber versionsnap = new ModuleVersionNumber("1.0-SNAPSHOT"); + + assertFalse(version0.equals(version1)); + assertTrue(version1.equals(version2)); + assertFalse(version2.equals(version3)); + assertTrue(version3.equals(version4)); + assertFalse(version4.equals(version5)); + assertTrue(version0.equals(version6)); + assertFalse(versiona.equals(version0)); + assertFalse(versiona.equals(versionb)); + assertFalse(versionsnap.equals(version6)); + assertFalse(versionsnap.equals(versiona)); + assertFalse(versionsnap.equals(versionb)); + } + + public void testCompare() + { + ModuleVersionNumber version0 = new ModuleVersionNumber("1"); + ModuleVersionNumber version1 = new ModuleVersionNumber("1.2"); + ModuleVersionNumber version2 = new ModuleVersionNumber("1.2"); + ModuleVersionNumber version3 = new ModuleVersionNumber("1.2.3"); + ModuleVersionNumber version4 = new ModuleVersionNumber("1.11"); + ModuleVersionNumber version5 = new ModuleVersionNumber("1.3.3"); + ModuleVersionNumber version6 = new ModuleVersionNumber("2.0"); + ModuleVersionNumber version7 = new ModuleVersionNumber("2.0.1"); + ModuleVersionNumber version8 = new ModuleVersionNumber("10.0"); + ModuleVersionNumber version9 = new ModuleVersionNumber("10.3"); + ModuleVersionNumber version10 = new ModuleVersionNumber("11.1"); + + assertEquals(-1, version0.compareTo(version1)); + assertEquals(1, version1.compareTo(version0)); + assertEquals(0, version1.compareTo(version2)); + assertEquals(-1, version2.compareTo(version3)); + assertEquals(-1, version2.compareTo(version4)); + assertEquals(-1, version3.compareTo(version5)); + assertEquals(1, version6.compareTo(version5)); + assertEquals(-1, version6.compareTo(version7)); + assertEquals(-1, version1.compareTo(version8)); + assertEquals(-1, version8.compareTo(version9)); + assertEquals(-1, version9.compareTo(version10)); + + ModuleVersionNumber version1point4 = new ModuleVersionNumber("1.4"); + ModuleVersionNumber version1point4a = new ModuleVersionNumber("1.4.a"); + ModuleVersionNumber version1point4b = new ModuleVersionNumber("1.4.b"); + ModuleVersionNumber version1point4c = new ModuleVersionNumber("1.4.c"); + ModuleVersionNumber version1point4d = new ModuleVersionNumber("1.4.d"); + ModuleVersionNumber version1point4snapshot = new ModuleVersionNumber("1.4-SNAPSHOT"); + ModuleVersionNumber version1point40 = new ModuleVersionNumber("1.4.0"); + + assertEquals(1, ModuleVersionNumber.VERSION_BIG.compareTo(version1)); + assertEquals(1, ModuleVersionNumber.VERSION_BIG.compareTo(version0)); + assertEquals(1, ModuleVersionNumber.VERSION_BIG.compareTo(version8)); + assertEquals(1, ModuleVersionNumber.VERSION_BIG.compareTo(version1point4b)); + assertEquals(1, ModuleVersionNumber.VERSION_BIG.compareTo(version1point4snapshot)); + + assertEquals(0, version1point4.compareTo(new ModuleVersionNumber("1.4"))); + assertTrue(version1point4.compareTo(version1point4a) < 1); + assertTrue(version1point4.compareTo(version1point4snapshot) > 0); + + assertTrue(version1point4b.compareTo(version1point4a) > 0); + assertTrue(version1point4b.compareTo(version1point4snapshot) > 0); + + assertTrue(version1point4c.compareTo(version1point4b) > 0); + assertTrue(version1point4c.compareTo(version1point4d) < 0); + + assertTrue(version1point4d.compareTo(version1point4c) > 0); + assertTrue(version1point40.compareTo(version1point4) == 0);// the same + + ModuleVersionNumber versionBase = new ModuleVersionNumber("0.1"); + ModuleVersionNumber versionMixed = new ModuleVersionNumber("0.1-incubating-unreleased"); + assertTrue(versionMixed.compareTo(versionBase) > 0); + + versionBase = new ModuleVersionNumber("3.2.6"); + versionMixed = new ModuleVersionNumber("3.2.6-alfresco-patched"); + assertTrue(versionMixed.compareTo(versionBase) > 0); + + versionBase = new ModuleVersionNumber("0.2"); + versionMixed = new ModuleVersionNumber("0.2-20120518"); + assertTrue(versionMixed.compareTo(versionBase) > 0); + } + + public void testSerialize() throws IOException, ClassNotFoundException + { + ModuleVersionNumber version0Before = new ModuleVersionNumber("1"); + ModuleVersionNumber version6Before = new ModuleVersionNumber("1.0"); + ModuleVersionNumber versionaBefore = new ModuleVersionNumber("1.0.a"); + ModuleVersionNumber versionbBefore = new ModuleVersionNumber("1.0.b"); + ModuleVersionNumber versionsnapBefore = new ModuleVersionNumber("1.0-SNAPSHOT"); + + //read and write versions then check they are the same. + ModuleVersionNumber version0 = writeAndRead(version0Before); + ModuleVersionNumber version6 = writeAndRead(version6Before); + ModuleVersionNumber versiona = writeAndRead(versionaBefore); + ModuleVersionNumber versionb = writeAndRead(versionbBefore); + ModuleVersionNumber versionsnap = writeAndRead(versionsnapBefore); + + assertTrue(version0.equals(version0Before)); + assertTrue(version6.equals(version6Before)); + assertTrue(versiona.equals(versionaBefore)); + assertTrue(versionb.equals(versionbBefore)); + assertTrue(versionsnap.equals(versionsnapBefore)); + + assertTrue(version0.equals(version6)); + assertFalse(versiona.equals(version0)); + assertFalse(versiona.equals(versionb)); + assertFalse(versionsnap.equals(version6)); + assertFalse(versionsnap.equals(versiona)); + assertFalse(versionsnap.equals(versionb)); + } + + private ModuleVersionNumber writeAndRead(ModuleVersionNumber versionNumber) throws IOException, ClassNotFoundException + { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(baos); + oos.writeObject(versionNumber); + oos.flush(); + oos.close(); + + ObjectInputStream objectInputStream = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray())); + return (ModuleVersionNumber) objectInputStream.readObject(); + } +} diff --git a/source/test-java/org/alfresco/repo/module/tool/WarHelperImplTest.java b/source/test-java/org/alfresco/repo/module/tool/WarHelperImplTest.java index 6ab3a42469..02dcdaef37 100644 --- a/source/test-java/org/alfresco/repo/module/tool/WarHelperImplTest.java +++ b/source/test-java/org/alfresco/repo/module/tool/WarHelperImplTest.java @@ -6,7 +6,6 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.File; -import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; @@ -14,6 +13,7 @@ import java.io.OutputStream; import java.util.Properties; import org.alfresco.repo.module.ModuleDetailsImpl; +import org.alfresco.repo.module.ModuleVersionNumber; import org.alfresco.service.cmr.module.ModuleDetails; import org.alfresco.util.TempFileProvider; import org.alfresco.util.VersionNumber; @@ -23,7 +23,6 @@ import org.springframework.util.FileCopyUtils; import de.schlichtherle.truezip.file.TArchiveDetector; import de.schlichtherle.truezip.file.TConfig; import de.schlichtherle.truezip.file.TFile; -import de.schlichtherle.truezip.file.TFileInputStream; import de.schlichtherle.truezip.fs.archive.zip.ZipDriver; import de.schlichtherle.truezip.socket.sl.IOPoolLocator; @@ -76,7 +75,7 @@ public class WarHelperImplTest extends WarHelperImpl { TFile theWar = getFile(".war", "module/test.war"); //Version 4.1.0 - ModuleDetails installingModuleDetails = new ModuleDetailsImpl("test_it", new VersionNumber("9999"), "Test Mod", "Testing module"); + ModuleDetails installingModuleDetails = new ModuleDetailsImpl("test_it", new ModuleVersionNumber("9999"), "Test Mod", "Testing module"); installingModuleDetails.setRepoVersionMin(new VersionNumber("10.1")); try { @@ -131,7 +130,7 @@ public class WarHelperImplTest extends WarHelperImpl { //Now check the compatible versions using the manifest TFile theWar = getFile(".war", "module/share-3.4.11.war"); - ModuleDetails installingModuleDetails = new ModuleDetailsImpl("test_it", new VersionNumber("9999"), "Test Mod", "Testing module"); + ModuleDetails installingModuleDetails = new ModuleDetailsImpl("test_it", new ModuleVersionNumber("9999"), "Test Mod", "Testing module"); installingModuleDetails.setRepoVersionMin(new VersionNumber("10.1")); try { @@ -181,7 +180,7 @@ public class WarHelperImplTest extends WarHelperImpl } theWar = getFile(".war", "module/share-4.2.a.war"); - installingModuleDetails = new ModuleDetailsImpl("test_it", new VersionNumber("9999"), "Test Mod", "Testing module"); + installingModuleDetails = new ModuleDetailsImpl("test_it", new ModuleVersionNumber("9999"), "Test Mod", "Testing module"); installingModuleDetails.setRepoVersionMin(new VersionNumber("101.1")); //this should fail BUT we are using a non-numeric version number so instead it passes without validation this.checkCompatibleVersionUsingManifest(theWar, installingModuleDetails); @@ -312,7 +311,7 @@ public class WarHelperImplTest extends WarHelperImpl { TFile theWar = getFile(".war", "module/empty.war"); - ModuleDetails installingModuleDetails = new ModuleDetailsImpl("test_it", new VersionNumber("9999"), "Test Mod", "Testing module"); + ModuleDetails installingModuleDetails = new ModuleDetailsImpl("test_it", new ModuleVersionNumber("9999"), "Test Mod", "Testing module"); installingModuleDetails.setRepoVersionMin(new VersionNumber("10.1")); this.checkCompatibleVersion(theWar, installingModuleDetails); //does not throw exception this.checkCompatibleEdition(theWar, installingModuleDetails); //does not throw exception