Checkpoint checkin of patch code.

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@2119 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2006-01-16 19:49:34 +00:00
parent 0c09d0ccc1
commit 47449b1555
19 changed files with 1401 additions and 1 deletions

View File

@@ -0,0 +1,232 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.repo.admin.patch;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Collections;
import java.util.List;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.transaction.TransactionUtil;
import org.alfresco.repo.transaction.TransactionUtil.TransactionWork;
import org.alfresco.service.cmr.admin.PatchException;
import org.alfresco.service.transaction.TransactionService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Base implementation of the patch. This class ensures that the patch is
* thread- and transaction-safe.
*
* @author Derek Hulley
*/
public abstract class AbstractPatch implements Patch
{
private static Log logger = LogFactory.getLog(AbstractPatch.class);
private String id;
private String applyAfterVersion;
private String description;
/** a list of patches that this one depends on */
private List<Patch> dependsOn;
/** flag indicating if the patch was successfully applied */
private boolean applied;
private TransactionService transactionService;
public AbstractPatch()
{
this.applied = false;
this.dependsOn = Collections.emptyList();
}
@Override
public String toString()
{
StringBuilder sb = new StringBuilder(56);
sb.append("Patch")
.append("[id=").append(getId())
.append(", after=").append(getApplyAfterVersion())
.append(", description=").append(getDescription())
.append("]");
return sb.toString();
}
/**
* Set the transaction provider so that each execution can be performed within a transaction
*/
public void setTransactionService(TransactionService transactionService)
{
this.transactionService = transactionService;
}
public String getId()
{
return id;
}
/**
*
* @param id the unique ID of the patch. This dictates the order in which patches are applied.
*/
public void setId(String id)
{
this.id = id;
}
public String getApplyAfterVersion()
{
return applyAfterVersion;
}
/**
*
* @param applyAfterVersion the version of the repository after which this patch must be applied.
*/
public void setApplyAfterVersion(String applyAfterVersion)
{
this.applyAfterVersion = applyAfterVersion;
}
public String getDescription()
{
return description;
}
/**
* @param description a thorough description of the patch
*/
public void setDescription(String description)
{
this.description = description;
}
public List<Patch> getDependsOn()
{
return this.dependsOn;
}
/**
* Set all the dependencies for this patch. It should not be executed
* before all the dependencies have been applied.
*
* @param dependsOn a list of dependencies
*/
public void setDependsOn(List<Patch> dependsOn)
{
this.dependsOn = dependsOn;
}
/**
* Sets up the transaction and ensures thread-safety.
*
* @see #applyInternal()
*/
public synchronized String apply() throws PatchException
{
// ensure that this has not been executed already
if (applied)
{
throw new AlfrescoRuntimeException("The patch has already been executed: \n" +
" patch: " + this);
}
// check that the necessary properties have been set
if (id == null || applyAfterVersion == null || description == null)
{
throw new AlfrescoRuntimeException(
"Patch properties 'id', 'applyAfterVersion' and 'description' have not all been set on this patch: \n" +
" patch: " + this);
}
else if (transactionService == null)
{
throw new AlfrescoRuntimeException("'transactionService' property has not been set: \n" +
" patch: " + this);
}
// execute in a transaction
try
{
TransactionWork<String> patchWork = new TransactionWork<String>()
{
public String doWork() throws Exception
{
String report = applyInternal();
// done
return report;
};
};
String report = TransactionUtil.executeInUserTransaction(transactionService, patchWork);
// the patch was successfully applied
applied = true;
// done
if (logger.isDebugEnabled())
{
logger.debug("Patch successfully applied: \n" +
" patch: " + this + "\n" +
" report: " + report);
}
return report;
}
catch (PatchException e)
{
// no need to extract the exception
throw e;
}
catch (Throwable e)
{
// check whether there is an embedded patch exception
Throwable cause = e.getCause();
if (cause != null && cause instanceof PatchException)
{
throw (PatchException) cause;
}
// need to generate a message from the exception
String report = makeReport(e);
// generate the correct exception
throw new PatchException(report);
}
}
/**
* Dumps the error's full message and trace to the String
*
* @param e the throwable
* @return Returns a String representative of the printStackTrace method
*/
private String makeReport(Throwable e)
{
StringWriter stringWriter = new StringWriter(1024);
PrintWriter printWriter = new PrintWriter(stringWriter, true);
try
{
e.printStackTrace(printWriter);
return stringWriter.toString();
}
finally
{
printWriter.close();
}
}
/**
* This method does the work. All transactions and thread-safety will be taken care of by this class.
* Any exception will result in the transaction being rolled back.
*
* @return Returns the report (only success messages).
* @see #apply()
* @throws Exception anything can be thrown. This must be used for all failures.
*/
protected abstract String applyInternal() throws Exception;
}

View File

@@ -0,0 +1,58 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.repo.admin.patch;
import java.util.List;
import org.alfresco.service.cmr.admin.PatchException;
/**
* A patch is an executable class that makes a change to persisted data.
* <p>
* Auditing information is not maintained by the patch - rather it is solely
* responsible for the execution of the processes necessary to apply the patch.
* <p>
* Patches must not be reappliable. It is up to the patch management systems
* to ensure that patches are <b>never reapplied</b>.
*
* @since 1.2
* @author Derek Hulley
*/
public interface Patch
{
public String getId();
public String getDescription();
public String getApplyAfterVersion();
/**
* Get patches that this patch depends on
*
* @return Returns a list of patches
*/
public List<Patch> getDependsOn();
/**
* Applies the patch. Typically this will be within the bounds of a new
* transaction.
*
* @return Returns the patch execution report
* @throws PatchException if the patch failed to be applied
*/
public String apply() throws PatchException;
}

View File

@@ -0,0 +1,54 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.repo.admin.patch;
import java.util.List;
import org.alfresco.repo.domain.AppliedPatch;
/**
* Provides data access support for patch persistence.
*
* @since 1.2
* @author Derek Hulley
*/
public interface PatchDaoService
{
/**
* Creates and saves a new instance of the patch. This will not have all the mandatory
* properties set - only the ID.
*
* @param id the unique key
* @return Returns a new instance that can be manipulated
*/
public AppliedPatch newAppliedPatch(String id);
/**
* Retrieve an existing patch
*
* @param id the patch unique ID
* @return Returns the patch instance or null if one has not been persisted
*/
public AppliedPatch getAppliedPatch(String id);
/**
* Get a list of all applied patches
*
* @return Returns a list of all applied patches
*/
public List<AppliedPatch> getAppliedPatches();
}

View File

@@ -0,0 +1,58 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.repo.admin.patch;
import java.util.List;
import org.alfresco.service.cmr.admin.PatchInfo;
/**
* Manages patches applied against the repository.
* <p>
* Patches are injected into this class and any attempted applications are recorded
* for later auditing.
*
* @since 1.2
* @author Derek Hulley
*/
public interface PatchService
{
/**
* Set the complete list of patches. All patch IDs must remain static for the duration their
* existence. This allows us to recognise the
*
* @param patches the complete list of patches (either applied or not)
*/
public void setPatches(List<Patch> patches);
/**
* Get a list of all previously applied patches
*
* @return Returns a list of patch application information
*/
public List<PatchInfo> getAppliedPatches();
/**
* Apply all outstanding patches that are relevant to the repo.
* If there is a failure, then the patches that were applied will remain so,
* but the process will not attempt to apply any further patches.
*
* @return Returns true if all outstanding patches were applied, or false if the process
* was termintated before all patches could be applied.
*/
public boolean applyOutstandingPatches();
}

View File

@@ -0,0 +1,230 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.repo.admin.patch;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.alfresco.repo.domain.AppliedPatch;
import org.alfresco.service.cmr.admin.PatchException;
import org.alfresco.service.cmr.admin.PatchInfo;
import org.alfresco.service.descriptor.Descriptor;
import org.alfresco.service.descriptor.DescriptorService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Manages patches applied against the repository.
* <p>
* Patches are injected into this class and any attempted applications are recorded
* for later auditing.
*
* @since 1.2
* @author Derek Hulley
*/
public class PatchServiceImpl implements PatchService
{
private static Log logger = LogFactory.getLog(PatchServiceImpl.class);
private DescriptorService descriptorService;
private PatchDaoService patchDaoService;
private List<Patch> patches;
public void setDescriptorService(DescriptorService descriptorService)
{
this.descriptorService = descriptorService;
}
public void setPatchDaoService(PatchDaoService patchDaoService)
{
this.patchDaoService = patchDaoService;
}
public void setPatches(List<Patch> patches)
{
this.patches = patches;
}
public List<PatchInfo> getAppliedPatches()
{
// get all the persisted patches
List<AppliedPatch> appliedPatches = patchDaoService.getAppliedPatches();
List<PatchInfo> patchInfos = new ArrayList<PatchInfo>(appliedPatches.size());
for (AppliedPatch patch : appliedPatches)
{
PatchInfo patchInfo = new PatchInfo(patch);
patchInfos.add(patchInfo);
}
// done
if (logger.isDebugEnabled())
{
logger.debug("Retrieved list of " + patchInfos.size() + " applied patches: \n");
}
return patchInfos;
}
public boolean applyOutstandingPatches()
{
// construct a map of all known patches by ID
Map<String, Patch> allPatchesById = new HashMap<String, Patch>(23);
for (Patch patch : patches)
{
allPatchesById.put(patch.getId(), patch);
}
// construct a list of executed patches by ID
Map<String, PatchInfo> appliedPatchInfosById = new HashMap<String, PatchInfo>(23);
List<PatchInfo> appliedPatches = getAppliedPatches();
for (PatchInfo patchInfo : appliedPatches)
{
// ignore unsuccessful attempts - we need to try them again
if (!patchInfo.getSucceeded())
{
continue;
}
appliedPatchInfosById.put(patchInfo.getId(), patchInfo);
}
// go through all the patches and apply them where necessary
boolean success = true;
for (Patch patch : allPatchesById.values())
{
// apply the patch
success = applyPatchAndDependencies(patch, appliedPatchInfosById);
if (!success)
{
// we failed to apply a patch or one of its dependencies - terminate
break;
}
}
// done
return success;
}
/**
* Reentrant method that ensures that a patch and all its dependencies get applied.
* The process terminates on the first failure.
*
* @param patchInfos all the executed patch data. If there was a failure, then this
* is the list of successful executions only.
* @param patch the patch (containing dependencies) to apply
* @param appliedPatchInfosById already applied patches
* @return Returns true if the patch and all its dependencies were successfully applied.
*/
private boolean applyPatchAndDependencies(Patch patch, Map<String, PatchInfo> appliedPatchInfosById)
{
String id = patch.getId();
// check if it has already been done
PatchInfo patchInfo = appliedPatchInfosById.get(id);
if (patchInfo != null && patchInfo.getSucceeded())
{
// this has already been done
return true;
}
// ensure that dependencies have been done
List<Patch> dependencies = patch.getDependsOn();
for (Patch dependencyPatch : dependencies)
{
boolean success = applyPatchAndDependencies(dependencyPatch, appliedPatchInfosById);
if (!success)
{
// a patch failed to be applied
return false;
}
}
// all the dependencies were successful
patchInfo = applyPatch(patch);
if (!patchInfo.getSucceeded())
{
// this was a failure
return false;
}
else
{
// it was successful - add it to the map of successful patches
appliedPatchInfosById.put(id, patchInfo);
return true;
}
}
private PatchInfo applyPatch(Patch patch)
{
// get the patch from the DAO
AppliedPatch appliedPatch = patchDaoService.getAppliedPatch(patch.getId());
if (appliedPatch != null && appliedPatch.getSucceeded())
{
// it has already been applied
PatchInfo patchInfo = new PatchInfo(appliedPatch);
// done
if (logger.isDebugEnabled())
{
logger.debug("Patch was already successfully applied: \n" +
" patch: " + patchInfo);
}
return patchInfo;
}
// the execution report
String report = null;
boolean success = false;
// first check whether the patch is relevant to the repo
Descriptor repo = descriptorService.getRepositoryDescriptor();
String versionLabel = repo.getVersionLabel();
if (versionLabel.compareTo(patch.getApplyAfterVersion()) >= 0)
{
// create a dummy report
StringBuilder sb = new StringBuilder(128);
sb.append("Patch ").append(patch.getId()).append(" was not relevant.");
report = sb.toString();
success = true; // this succeeded because it didn't need to be applied
}
else
{
// perform actual execution
try
{
report = patch.apply();
success = true;
}
catch (PatchException e)
{
// failed
report = e.getMessage();
success = false;
}
}
// create a record for the execution
appliedPatch = patchDaoService.newAppliedPatch(patch.getId());
// fill in the record's details
appliedPatch.setDescription(patch.getDescription());
appliedPatch.setApplyAfterVersion(patch.getApplyAfterVersion());
appliedPatch.setSucceeded(success);
appliedPatch.setAppliedOnVersion(versionLabel);
appliedPatch.setAppliedOnDate(new Date());
appliedPatch.setReport(report);
// create the info for returning
PatchInfo patchInfo = new PatchInfo(appliedPatch);
// done
if (logger.isDebugEnabled())
{
logger.debug("Applied patch: \n" + patchInfo);
}
return patchInfo;
}
}

View File

@@ -0,0 +1,142 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.repo.admin.patch;
import java.util.ArrayList;
import java.util.List;
import junit.framework.TestCase;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.service.cmr.admin.PatchException;
import org.alfresco.service.cmr.admin.PatchInfo;
import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.ApplicationContextHelper;
import org.springframework.context.ApplicationContext;
/**
* @see org.alfresco.repo.admin.patch.Patch
* @see org.alfresco.repo.admin.patch.AbstractPatch
* @see org.alfresco.repo.admin.patch.PatchService
*
* @author Derek Hulley
*/
public class PatchTest extends TestCase
{
private static final ApplicationContext ctx = ApplicationContextHelper.getApplicationContext();
private TransactionService transactionService;
private PatchService patchService;
private List<Patch> patches;
public PatchTest(String name)
{
super(name);
}
public void setUp() throws Exception
{
transactionService = (TransactionService) ctx.getBean("transactionComponent");
patchService = (PatchService) ctx.getBean("PatchService");
// get the patches to play with
patches = new ArrayList<Patch>(2);
patches.add((Patch)ctx.getBean("patch.sample.02"));
patches.add((Patch)ctx.getBean("patch.sample.01"));
patchService.setPatches(patches);
}
public void testSetup() throws Exception
{
assertNotNull(transactionService);
assertNotNull(patchService);
}
public void testSimplePatchSuccess() throws Exception
{
Patch patch = new SamplePatch(false, transactionService);
String report = patch.apply();
// check that the report was generated
assertEquals("Patch report incorrect", SamplePatch.MSG_SUCCESS, report);
}
public void testPatchReapplication()
{
// successfully apply a patch
Patch patch = new SamplePatch(false, transactionService);
patch.apply();
// check that the patch cannot be reapplied
try
{
patch.apply();
fail("AbstractPatch failed to prevent reapplication");
}
catch (AlfrescoRuntimeException e)
{
// expected
}
// apply an unsuccessful patch
patch = new SamplePatch(true, transactionService);
try
{
patch.apply();
fail("Failed patch didn't throw PatchException");
}
catch (PatchException e)
{
// expected
}
// repeat
try
{
patch.apply();
fail("Reapplication of failed patch didn't throw PatchException");
}
catch (PatchException e)
{
// expected
}
}
public void testApplyOutstandingPatches() throws Exception
{
// apply outstanding patches
boolean success = patchService.applyOutstandingPatches();
assertTrue(success);
// get applied patches
List<PatchInfo> patchInfos = patchService.getAppliedPatches();
// check that the patch application was recorded
boolean found01 = false;
boolean found02 = false;
for (PatchInfo patchInfo : patchInfos)
{
if (patchInfo.getId().equals("Sample01"))
{
found01 = true;
assertTrue("Patch info didn't indicate success: " + patchInfo, patchInfo.getSucceeded());
}
else if (patchInfo.getId().equals("Sample02"))
{
found02 = true;
assertTrue("Patch info didn't indicate success: " + patchInfo, patchInfo.getSucceeded());
}
}
assertTrue("Sample 01 not in list of applied patches", found01);
assertTrue("Sample 02 not in list of applied patches", found02);
}
}

View File

@@ -0,0 +1,66 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.repo.admin.patch;
import org.alfresco.service.transaction.TransactionService;
public class SamplePatch extends AbstractPatch
{
public static final String MSG_SUCCESS = "SamplePatch applied successfully";
public static final String MSG_FAILURE = "SamplePatch failed to apply";
private boolean mustFail;
/**
* Default constructor for Spring config
*/
public SamplePatch()
{
}
/**
* Helper constructor for some tests. Default properties are set automatically.
*
* @param mustFail true if this instance must always fail to apply
*/
/* protected */ SamplePatch(boolean mustFail, TransactionService transactionService)
{
this.mustFail = mustFail;
setTransactionService(transactionService);
setId("SamplePatch");
setDescription("This is a sample patch");
setApplyAfterVersion("1.0.0");
}
/**
* Does nothing
*
* @return Returns a success or failure message dependent on the constructor used
*/
@Override
protected String applyInternal() throws Exception
{
if (mustFail)
{
throw new Exception(MSG_FAILURE);
}
else
{
return MSG_SUCCESS;
}
}
}

View File

@@ -0,0 +1,83 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.repo.admin.patch.hibernate;
import java.util.List;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.admin.patch.PatchDaoService;
import org.alfresco.repo.domain.AppliedPatch;
import org.alfresco.repo.domain.hibernate.AppliedPatchImpl;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
/**
* Hibernate-specific implementation for managing patch persistence.
*
* @since 1.2
* @author Derek Hulley
*/
public class HibernatePatchDaoServiceImpl extends HibernateDaoSupport implements PatchDaoService
{
public static final String QUERY_GET_ALL_APPLIED_PATCHES = "patch.GetAllAppliedPatches";
public AppliedPatch newAppliedPatch(String id)
{
// check for existence
AppliedPatch existing = getAppliedPatch(id);
if (existing != null)
{
throw new AlfrescoRuntimeException("An applied patch already exists: \n" +
" id: " + id);
}
// construct a new one
AppliedPatchImpl patch = new AppliedPatchImpl();
patch.setId(id);
// save this in hibernate
getHibernateTemplate().save(patch);
// done
return patch;
}
public AppliedPatch getAppliedPatch(String id)
{
AppliedPatch patch = (AppliedPatch) getHibernateTemplate().get(AppliedPatchImpl.class, id);
// done
return patch;
}
/**
* @see #QUERY_GET_ALL_APPLIED_PATCHES
*/
@SuppressWarnings("unchecked")
public List<AppliedPatch> getAppliedPatches()
{
HibernateCallback callback = new HibernateCallback()
{
public Object doInHibernate(Session session)
{
Query query = session.getNamedQuery(HibernatePatchDaoServiceImpl.QUERY_GET_ALL_APPLIED_PATCHES);
return query.list();
}
};
List<AppliedPatch> queryResults = (List) getHibernateTemplate().execute(callback);
// done
return queryResults;
}
}

View File

@@ -0,0 +1,48 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.repo.domain;
import java.util.Date;
/**
* Interface for persistent patch application information.
*
* @author Derek Hulley
*/
public interface AppliedPatch
{
public String getId();
public void setId(String id);
public String getDescription();
public void setDescription(String description);
public String getApplyAfterVersion();
public void setApplyAfterVersion(String version);
public boolean getSucceeded();
public void setSucceeded(boolean succeeded);
public String getAppliedOnVersion();
public void setAppliedOnVersion(String version);
public Date getAppliedOnDate();
public void setAppliedOnDate(Date date);
public String getReport();
public void setReport(String report);
}

View File

@@ -0,0 +1,33 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
'-//Hibernate/Hibernate Mapping DTD 3.0//EN'
'http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd'>
<hibernate-mapping>
<class
name="org.alfresco.repo.domain.hibernate.AppliedPatchImpl"
proxy="org.alfresco.repo.domain.AppliedPatch"
table="applied_patch"
dynamic-update="false"
dynamic-insert="false"
select-before-update="false"
optimistic-lock="version" >
<id column="id" length="32" name="id" type="string" />
<property name="description" column="description" type="string" length="1024" />
<property name="applyAfterVersion" column="apply_after_version" type="string" length="10" />
<property name="succeeded" column="succeeded" type="boolean" />
<property name="appliedOnVersion" column="applied_on_version" type="string" length="10" />
<property name="appliedOnDate" column="applied_on_date" type="timestamp" />
<property name="report" column="report" type="string" length="1024" />
</class>
<query name="patch.GetAllAppliedPatches">
select
appliedPatch
from
org.alfresco.repo.domain.hibernate.AppliedPatchImpl as appliedPatch
</query>
</hibernate-mapping>

View File

@@ -0,0 +1,110 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.repo.domain.hibernate;
import java.util.Date;
import org.alfresco.repo.domain.AppliedPatch;
/**
* Hibernate-specific implementation of the persistent object.
*
* @author Derek Hulley
*/
public class AppliedPatchImpl implements AppliedPatch
{
private String id;
private String description;
private String applyAfterVersion;
private boolean succeeded;
private String appliedOnVersion;
private Date appliedOnDate;
private String report;
public String getId()
{
return id;
}
public void setId(String id)
{
this.id = id;
}
public String getDescription()
{
return description;
}
public void setDescription(String description)
{
if (description.length() > 1024)
{
// truncate as necessary
description = (description.substring(0, 1020) + "...");
}
this.description = description;
}
public String getAppliedOnVersion()
{
return appliedOnVersion;
}
public void setAppliedOnVersion(String appliedOnVersion)
{
this.appliedOnVersion = appliedOnVersion;
}
public boolean getSucceeded()
{
return succeeded;
}
public void setSucceeded(boolean succeeded)
{
this.succeeded = succeeded;
}
public String getApplyAfterVersion()
{
return applyAfterVersion;
}
public void setApplyAfterVersion(String applyAfterVersion)
{
this.applyAfterVersion = applyAfterVersion;
}
public Date getAppliedOnDate()
{
return appliedOnDate;
}
public void setAppliedOnDate(Date appliedOnDate)
{
this.appliedOnDate = appliedOnDate;
}
public String getReport()
{
return report;
}
public void setReport(String report)
{
if (report.length() > 1024)
{
// truncate as necessary
report = (report.substring(0, 1020) + "...");
}
this.report = report;
}
}

View File

@@ -32,7 +32,6 @@ import org.alfresco.repo.domain.PropertyValue;
import org.alfresco.repo.domain.Store;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
import org.hibernate.mapping.Bag;
/**
* Bean containing all the persistence data representing a <b>node</b>.
@@ -136,6 +135,7 @@ public class NodeImpl implements Node
/**
* For Hibernate use
*/
@SuppressWarnings("unused")
private void setAspects(Set<QName> aspects)
{
this.aspects = aspects;
@@ -149,6 +149,7 @@ public class NodeImpl implements Node
/**
* For Hibernate use
*/
@SuppressWarnings("unused")
private void setSourceNodeAssocs(Collection<NodeAssoc> sourceNodeAssocs)
{
this.sourceNodeAssocs = sourceNodeAssocs;
@@ -162,6 +163,7 @@ public class NodeImpl implements Node
/**
* For Hibernate use
*/
@SuppressWarnings("unused")
private void setTargetNodeAssocs(Collection<NodeAssoc> targetNodeAssocs)
{
this.targetNodeAssocs = targetNodeAssocs;
@@ -175,6 +177,7 @@ public class NodeImpl implements Node
/**
* For Hibernate use
*/
@SuppressWarnings("unused")
private void setParentAssocs(Collection<ChildAssoc> parentAssocs)
{
this.parentAssocs = parentAssocs;
@@ -188,6 +191,7 @@ public class NodeImpl implements Node
/**
* For Hibernate use
*/
@SuppressWarnings("unused")
private void setChildAssocs(Collection<ChildAssoc> childAssocs)
{
this.childAssocs = childAssocs;
@@ -201,6 +205,7 @@ public class NodeImpl implements Node
/**
* For Hibernate use
*/
@SuppressWarnings("unused")
private void setProperties(Map<QName, PropertyValue> properties)
{
this.properties = properties;