diff --git a/source/java/org/alfresco/repo/domain/QNameDAO.java b/source/java/org/alfresco/repo/domain/QNameDAO.java index 7e0d25fbde..5f18857890 100644 --- a/source/java/org/alfresco/repo/domain/QNameDAO.java +++ b/source/java/org/alfresco/repo/domain/QNameDAO.java @@ -67,6 +67,16 @@ public interface QNameDAO */ NamespaceEntity newNamespaceEntity(String namespaceUri); + /** + * Modifies an existing namespace URI. If the new URI already exists, then no + * new entity is created and a concurrency + * + * @param oldNamespaceUri the old namespace URI + * @param newNamespaceUri the new namespace URI + * @throws AlfrescoRuntimeException if the new namespace is in use + */ + void updateNamespaceEntity(String oldNamespaceUri, String newNamespaceUri); + /** * @param id the unique ID of the entity * @return the QName entity (never null) diff --git a/source/java/org/alfresco/repo/domain/QNameDAOTest.java b/source/java/org/alfresco/repo/domain/QNameDAOTest.java index 275b6c305e..08f8c80ffb 100644 --- a/source/java/org/alfresco/repo/domain/QNameDAOTest.java +++ b/source/java/org/alfresco/repo/domain/QNameDAOTest.java @@ -92,6 +92,34 @@ public class QNameDAOTest extends TestCase retryingTransactionHelper.doInTransaction(callback); } + public void testRenameNamespace() throws Exception + { + final String namespaceUriBefore = GUID.generate(); + final QName qnameBefore = QName.createQName(namespaceUriBefore, "before"); + final String namespaceUriAfter = GUID.generate(); + final QName qnameAfter = QName.createQName(namespaceUriAfter, "before"); + RetryingTransactionCallback callback = new RetryingTransactionCallback() + { + public Object execute() throws Throwable + { + dao.getOrCreateNamespaceEntity(namespaceUriBefore); + // Get a QName that has the URI + QNameEntity qnameEntityBefore = dao.getOrCreateQNameEntity(qnameBefore); + // Now modify the namespace + dao.updateNamespaceEntity(namespaceUriBefore, namespaceUriAfter); + // The old qname must be gone + assertNull("QName must be gone as the URI was renamed", dao.getQNameEntity(qnameBefore)); + // The new QName must be present and with the same ID + QNameEntity qnameEntityAfter = dao.getQNameEntity(qnameAfter); + assertNotNull("Expected QName with new URI to exist.", qnameEntityAfter); + assertEquals("QName changed ID unexpectedly.", qnameEntityBefore.getId(), qnameEntityAfter.getId()); + // Done + return null; + } + }; + retryingTransactionHelper.doInTransaction(callback); + } + public void testNewQName() throws Exception { final String namespaceUri = GUID.generate(); diff --git a/source/java/org/alfresco/repo/domain/hibernate/HibernateQNameDAOImpl.java b/source/java/org/alfresco/repo/domain/hibernate/HibernateQNameDAOImpl.java index b183fe9bd6..380c7c505c 100644 --- a/source/java/org/alfresco/repo/domain/hibernate/HibernateQNameDAOImpl.java +++ b/source/java/org/alfresco/repo/domain/hibernate/HibernateQNameDAOImpl.java @@ -116,6 +116,28 @@ public class HibernateQNameDAOImpl extends HibernateDaoSupport implements QNameD return namespace; } + public void updateNamespaceEntity(String oldNamespaceUri, String newNamespaceUri) + { + // First check for clashes + if (getNamespaceEntity(newNamespaceUri) != null) + { + throw new AlfrescoRuntimeException("Namespace URI '" + newNamespaceUri + "' already exists."); + } + // Get the old one + NamespaceEntity oldNamespaceEntity = getNamespaceEntity(oldNamespaceUri); + if (oldNamespaceEntity == null) + { + // Nothing to rename + return; + } + oldNamespaceEntity.setUri(newNamespaceUri); + // Flush to force early failure + getSession().flush(); + // Trash the cache + qnameEntityCache.clear(); + // Done + } + public QNameEntity getQNameEntity(Long id) { QNameEntity qnameEntity = (QNameEntity) getSession().get(QNameEntityImpl.class, id);