Merged V2.2 to HEAD

11106: Leniency in AVM CAL upgrade to avoid customer upgrade issues ACT-4500
   11129: ETWOTWO-460 Service Port for alfresco runtime
   11144: Proper clean-up of deleted node's properties and aspects
   11146: Modifications to enable 'alternatives' when running patches
   11153: Fixed masked NPE when checking 'alternative' patches
   11154: Some neat reporting when a patch doesn't execute as a result of an alternative patch having run
   11161: ETWOTWO-91
   11163: ETWOTWO-733: CheckOutCheckInService.getWorkingCopy(NodeRef) returns nodes ...
   11165: Merged V2.1 to V2.2
      10983: Close stream for audit config
   11192: ETWOTWO-169 -  Editing FSR Deployment Receiver causes password to be lost
   11210: Merge of refactored AVM Filesystem storeCreated Processing from 2.1


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@11227 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2008-10-07 02:01:55 +00:00
parent e6d7627f13
commit 1cd93731fd
16 changed files with 636 additions and 76 deletions

View File

@@ -78,32 +78,27 @@ public abstract class AbstractPatch implements Patch
private String description;
/** a list of patches that this one depends on */
private List<Patch> dependsOn;
/** a list of patches that, if already present, mean that this one should be ignored */
private List<Patch> alternatives;
/** flag indicating if the patch was successfully applied */
private boolean applied;
private boolean applyToTenants;
/** track completion * */
int percentComplete = 0;
/** start time * */
long startTime;
/** the service to register ourselves with */
private PatchService patchService;
/** used to ensure a unique transaction per execution */
protected TransactionService transactionService;
/** support service */
protected NamespaceService namespaceService;
/** support service */
protected NodeService nodeService;
/** support service */
protected SearchService searchService;
/** support service */
protected AuthenticationComponent authenticationComponent;
/** support service */
protected TenantAdminService tenantAdminService;
/** track completion * */
int percentComplete = 0;
/** start time * */
long startTime;
public AbstractPatch()
{
this.fixesFromSchema = -1;
@@ -112,6 +107,7 @@ public abstract class AbstractPatch implements Patch
this.applied = false;
this.applyToTenants = true; // by default, apply to each tenant, if tenant service is enabled
this.dependsOn = Collections.emptyList();
this.alternatives = Collections.emptyList();
}
@Override
@@ -144,33 +140,21 @@ public abstract class AbstractPatch implements Patch
this.transactionService = transactionService;
}
/**
* Set a generally-used service
*/
public void setNamespaceService(NamespaceService namespaceService)
{
this.namespaceService = namespaceService;
}
/**
* Set a generally-used service
*/
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
/**
* Set a generally-used service
*/
public void setSearchService(SearchService searchService)
{
this.searchService = searchService;
}
/**
* Set a generally-used service
*/
public void setAuthenticationComponent(AuthenticationComponent authenticationComponent)
{
this.authenticationComponent = authenticationComponent;
@@ -303,6 +287,22 @@ public abstract class AbstractPatch implements Patch
this.dependsOn = dependsOn;
}
public List<Patch> getAlternatives()
{
return alternatives;
}
/**
* Set all anti-dependencies. If any of the patches in the list have already been executed, then
* this one need not be.
*
* @param alternatives a list of alternative patches
*/
public void setAlternatives(List<Patch> alternatives)
{
this.alternatives = alternatives;
}
public boolean applies(int version)
{
return ((this.fixesFromSchema <= version) && (version <= fixesToSchema));
@@ -345,7 +345,9 @@ public abstract class AbstractPatch implements Patch
checkPropertyNotNull(authenticationComponent, "authenticationComponent");
if (fixesFromSchema == -1 || fixesToSchema == -1 || targetSchema == -1)
{
throw new AlfrescoRuntimeException("Patch properties 'fixesFromSchema', 'fixesToSchema' and 'targetSchema' have not all been set on this patch: \n"
throw new AlfrescoRuntimeException(
"Patch properties 'fixesFromSchema', 'fixesToSchema' and 'targetSchema' " +
"have not all been set on this patch: \n"
+ " patch: " + this);
}
}

View File

@@ -69,6 +69,13 @@ public interface Patch
*/
public List<Patch> getDependsOn();
/**
* Get patches that could have done the work already
*
* @return Returns a list of patches
*/
public List<Patch> getAlternatives();
/**
* Check if the patch is applicable to a given schema version.
*

View File

@@ -56,6 +56,7 @@ import org.apache.commons.logging.LogFactory;
public class PatchServiceImpl implements PatchService
{
private static final String MSG_NOT_RELEVANT = "patch.service.not_relevant";
private static final String MSG_PRECEEDED_BY_ALTERNATIVE = "patch.service.preceeded_by_alternative";
private static final String MSG_APPLYING_PATCH = "patch.service.applying_patch";
private static final Date ZERO_DATE = new Date(0L);
@@ -245,6 +246,7 @@ public class PatchServiceImpl implements PatchService
boolean success = false;
// first check whether the patch is relevant to the repo
Descriptor repoDescriptor = descriptorService.getInstalledRepositoryDescriptor();
String preceededByAlternative = preceededByAlternative(patch);
boolean applies = applies(repoDescriptor, patch);
if (!applies)
{
@@ -252,6 +254,11 @@ public class PatchServiceImpl implements PatchService
report = I18NUtil.getMessage(MSG_NOT_RELEVANT, repoDescriptor.getSchema());
success = true; // this succeeded because it didn't need to be applied
}
else if (preceededByAlternative != null)
{
report = I18NUtil.getMessage(MSG_PRECEEDED_BY_ALTERNATIVE, preceededByAlternative);
success = true; // this succeeded because it didn't need to be applied
}
else
{
// perform actual execution
@@ -309,6 +316,28 @@ public class PatchServiceImpl implements PatchService
return appliedPatch;
}
/**
* Identifies if one of the alternative patches has already been executed.
*
* @param patch the patch to check
* @return Returns the ID of any successfully executed alternative patch
*/
private String preceededByAlternative(Patch patch)
{
// If any alternatives were executed, then bypass this one
List<Patch> alternatives = patch.getAlternatives();
for (Patch alternative : alternatives)
{
// If the patch was executed, then this one was effectively executed
AppliedPatch appliedAlternative = patchDaoService.getAppliedPatch(alternative.getId());
if (appliedAlternative != null && appliedAlternative.getSucceeded())
{
return alternative.getId();
}
}
return null;
}
/**
* Check whether the patch is applicable to the particular version of the repository.
*

View File

@@ -0,0 +1,49 @@
/*
* Copyright (C) 2005-2008 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.admin.patch.impl;
import org.alfresco.i18n.I18NUtil;
import org.alfresco.repo.admin.patch.AbstractPatch;
/**
* Does nothing.
*
* @author Derek Hulley
* @since 2.2.2
*/
public class NoOpPatch extends AbstractPatch
{
private static final String MSG_RESULT = "patch.noOpPatch.result";
public NoOpPatch()
{
}
@Override
protected String applyInternal() throws Exception
{
return I18NUtil.getMessage(MSG_RESULT);
}
}