mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-31 17:39:05 +00:00
Fixed ETHREEOH-1719: Renaming 'Web Project' makes it a DM space and the AVMstore gets corrupted
- An injected list of namespaces determine whether a node's association path QName is modified during a rename or not: <property name="systemNamespaces"> <list> <value>http://www.alfresco.org/model/application/1.0</value> <value>http://www.alfresco.org/model/site/1.0</value> </list> </property> - Added a method to FileFolderService to specify the association QName on creation This is used by the tests, but can be used by apps as well. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@14262 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -14,6 +14,12 @@
|
|||||||
<property name="contentService"><ref bean="contentService" /></property>
|
<property name="contentService"><ref bean="contentService" /></property>
|
||||||
<property name="mimetypeService"><ref bean="mimetypeService" /></property>
|
<property name="mimetypeService"><ref bean="mimetypeService" /></property>
|
||||||
|
|
||||||
|
<property name="systemNamespaces">
|
||||||
|
<list>
|
||||||
|
<value>http://www.alfresco.org/model/application/1.0</value>
|
||||||
|
<value>http://www.alfresco.org/model/site/1.0</value>
|
||||||
|
</list>
|
||||||
|
</property>
|
||||||
<property name="systemPaths">
|
<property name="systemPaths">
|
||||||
<list>
|
<list>
|
||||||
<value>/${spaces.company_home.childname}</value>
|
<value>/${spaces.company_home.childname}</value>
|
||||||
|
@@ -103,6 +103,7 @@ public class FileFolderServiceImpl implements FileFolderService
|
|||||||
private SearchService searchService;
|
private SearchService searchService;
|
||||||
private ContentService contentService;
|
private ContentService contentService;
|
||||||
private MimetypeService mimetypeService;
|
private MimetypeService mimetypeService;
|
||||||
|
private Set<String> systemNamespaces;
|
||||||
|
|
||||||
// TODO: Replace this with a more formal means of identifying "system" folders (i.e. aspect or UUID)
|
// TODO: Replace this with a more formal means of identifying "system" folders (i.e. aspect or UUID)
|
||||||
private List<String> systemPaths;
|
private List<String> systemPaths;
|
||||||
@@ -112,6 +113,7 @@ public class FileFolderServiceImpl implements FileFolderService
|
|||||||
*/
|
*/
|
||||||
public FileFolderServiceImpl()
|
public FileFolderServiceImpl()
|
||||||
{
|
{
|
||||||
|
systemNamespaces = new HashSet<String>(5);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setNamespaceService(NamespaceService namespaceService)
|
public void setNamespaceService(NamespaceService namespaceService)
|
||||||
@@ -149,6 +151,22 @@ public class FileFolderServiceImpl implements FileFolderService
|
|||||||
this.mimetypeService = mimetypeService;
|
this.mimetypeService = mimetypeService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the namespaces that should be treated as 'system' namespaces.
|
||||||
|
* <p>
|
||||||
|
* When files or folders are renamed, the association path (QName) is normally
|
||||||
|
* modified to follow the name of the node. If, however, the namespace of the
|
||||||
|
* patch QName is in this list, the association path is left alone. This allows
|
||||||
|
* parts of the application to use well-known paths even if the end-user is
|
||||||
|
* able to modify the objects <b>cm:name</b> value.
|
||||||
|
*
|
||||||
|
* @param systemNamespaces a list of system namespaces
|
||||||
|
*/
|
||||||
|
public void setSystemNamespaces(List<String> systemNamespaces)
|
||||||
|
{
|
||||||
|
this.systemNamespaces.addAll(systemNamespaces);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Replace this with a more formal means of identifying "system" folders (i.e. aspect or UUID)
|
// TODO: Replace this with a more formal means of identifying "system" folders (i.e. aspect or UUID)
|
||||||
public void setSystemPaths(List<String> systemPaths)
|
public void setSystemPaths(List<String> systemPaths)
|
||||||
{
|
{
|
||||||
@@ -572,8 +590,9 @@ public class FileFolderServiceImpl implements FileFolderService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QName existingQName = assocRef.getQName();
|
||||||
QName qname;
|
QName qname;
|
||||||
if (nameChanged)
|
if (nameChanged && !systemNamespaces.contains(existingQName.getNamespaceURI()))
|
||||||
{
|
{
|
||||||
// Change the localname to match the new name
|
// Change the localname to match the new name
|
||||||
qname = QName.createQName(
|
qname = QName.createQName(
|
||||||
@@ -583,9 +602,7 @@ public class FileFolderServiceImpl implements FileFolderService
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Keep the localname
|
// Keep the localname
|
||||||
qname = QName.createQName(
|
qname = existingQName;
|
||||||
assocRef.getQName().getNamespaceURI(),
|
|
||||||
assocRef.getQName().getLocalName());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QName targetParentType = nodeService.getType(targetParentRef);
|
QName targetParentType = nodeService.getType(targetParentRef);
|
||||||
@@ -714,6 +731,16 @@ public class FileFolderServiceImpl implements FileFolderService
|
|||||||
}
|
}
|
||||||
|
|
||||||
public FileInfo create(NodeRef parentNodeRef, String name, QName typeQName) throws FileExistsException
|
public FileInfo create(NodeRef parentNodeRef, String name, QName typeQName) throws FileExistsException
|
||||||
|
{
|
||||||
|
return createImpl(parentNodeRef, name, typeQName, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FileInfo create(NodeRef parentNodeRef, String name, QName typeQName, QName assocQName) throws FileExistsException
|
||||||
|
{
|
||||||
|
return createImpl(parentNodeRef, name, typeQName, assocQName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private FileInfo createImpl(NodeRef parentNodeRef, String name, QName typeQName, QName assocQName) throws FileExistsException
|
||||||
{
|
{
|
||||||
// file or folder
|
// file or folder
|
||||||
boolean isFolder = false;
|
boolean isFolder = false;
|
||||||
@@ -738,16 +765,19 @@ public class FileFolderServiceImpl implements FileFolderService
|
|||||||
}
|
}
|
||||||
|
|
||||||
// create the node
|
// create the node
|
||||||
QName qname = QName.createQName(
|
if (assocQName == null)
|
||||||
NamespaceService.CONTENT_MODEL_1_0_URI,
|
{
|
||||||
QName.createValidLocalName(name));
|
assocQName = QName.createQName(
|
||||||
|
NamespaceService.CONTENT_MODEL_1_0_URI,
|
||||||
|
QName.createValidLocalName(name));
|
||||||
|
}
|
||||||
ChildAssociationRef assocRef = null;
|
ChildAssociationRef assocRef = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
assocRef = nodeService.createNode(
|
assocRef = nodeService.createNode(
|
||||||
parentNodeRef,
|
parentNodeRef,
|
||||||
ContentModel.ASSOC_CONTAINS,
|
ContentModel.ASSOC_CONTAINS,
|
||||||
qname,
|
assocQName,
|
||||||
typeQName,
|
typeQName,
|
||||||
properties);
|
properties);
|
||||||
}
|
}
|
||||||
|
@@ -299,6 +299,35 @@ public class FileFolderServiceImplTest extends TestCase
|
|||||||
assertNotNull("Folder info for new name is not present", checkInfo);
|
assertNotNull("Folder info for new name is not present", checkInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testRenameWithoutAssocQNameChange() throws Exception
|
||||||
|
{
|
||||||
|
FileInfo folderInfo = getByName(NAME_L0_FOLDER_A, true);
|
||||||
|
assertNotNull(folderInfo);
|
||||||
|
NodeRef folderNodeRef = folderInfo.getNodeRef();
|
||||||
|
// Create a child file
|
||||||
|
QName assocQName = QName.createQName(NamespaceService.APP_MODEL_1_0_URI, "abc");
|
||||||
|
NodeRef newFileNodeRef = fileFolderService.create(
|
||||||
|
folderNodeRef,
|
||||||
|
"AnotherFile.txt",
|
||||||
|
ContentModel.TYPE_CONTENT,
|
||||||
|
assocQName).getNodeRef();
|
||||||
|
// Make sure that the correct association QName was used
|
||||||
|
QName checkQName = nodeService.getPrimaryParent(newFileNodeRef).getQName();
|
||||||
|
assertEquals(
|
||||||
|
"The given assoc QName was not used for the path",
|
||||||
|
assocQName,
|
||||||
|
checkQName);
|
||||||
|
// Rename
|
||||||
|
String newName = "AnotherFile-new.txt";
|
||||||
|
folderInfo = fileFolderService.rename(newFileNodeRef, newName);
|
||||||
|
// Make sure that the association QName did not change
|
||||||
|
checkQName = nodeService.getPrimaryParent(newFileNodeRef).getQName();
|
||||||
|
assertEquals(
|
||||||
|
"The given assoc QName was not used for the path after a rename",
|
||||||
|
assocQName,
|
||||||
|
nodeService.getPrimaryParent(newFileNodeRef).getQName());
|
||||||
|
}
|
||||||
|
|
||||||
public void testRenameDuplicate() throws Exception
|
public void testRenameDuplicate() throws Exception
|
||||||
{
|
{
|
||||||
FileInfo folderInfo = getByName(NAME_L0_FOLDER_A, true);
|
FileInfo folderInfo = getByName(NAME_L0_FOLDER_A, true);
|
||||||
|
@@ -169,18 +169,37 @@ public interface FileFolderService
|
|||||||
throws FileExistsException, FileNotFoundException;
|
throws FileExistsException, FileNotFoundException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a file or folder; or any valid node of type derived from file or folder
|
* Create a file or folder; or any valid node of type derived from file or folder.
|
||||||
|
* <p>
|
||||||
|
* The association QName for the patch defaults to <b>cm:filename</b> i.e. the
|
||||||
|
* <b>Content Model</b> namespace with the filename as the local name.
|
||||||
*
|
*
|
||||||
* @param parentNodeRef the parent node. The parent must be a valid
|
* @param parentNodeRef the parent node. The parent must be a valid
|
||||||
* {@link org.alfresco.model.ContentModel#TYPE_CONTAINER container}.
|
* {@link org.alfresco.model.ContentModel#TYPE_FOLDER folder}.
|
||||||
* @param name the name of the node
|
* @param name the name of the node
|
||||||
* @param typeQName the type to create
|
* @param typeQName the type to create
|
||||||
* @return Returns the new node's file information
|
* @return Returns the new node's file information
|
||||||
* @throws FileExistsException
|
* @throws FileExistsException
|
||||||
|
*
|
||||||
|
* @see {@link #create(NodeRef, String, QName, QName)}
|
||||||
*/
|
*/
|
||||||
@Auditable(key = Auditable.Key.ARG_0, parameters = {"parentNodeRef", "name", "typeQName"})
|
@Auditable(key = Auditable.Key.ARG_0, parameters = {"parentNodeRef", "name", "typeQName"})
|
||||||
public FileInfo create(NodeRef parentNodeRef, String name, QName typeQName) throws FileExistsException;
|
public FileInfo create(NodeRef parentNodeRef, String name, QName typeQName) throws FileExistsException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a file or folder; or any valid node of type derived from file or folder
|
||||||
|
*
|
||||||
|
* @param parentNodeRef the parent node. The parent must be a valid
|
||||||
|
* {@link org.alfresco.model.ContentModel#TYPE_FOLDER folder}.
|
||||||
|
* @param name the name of the node
|
||||||
|
* @param typeQName the type to create
|
||||||
|
* @param assocQName the association QName to set for the path (may be <tt>null</tt>).
|
||||||
|
* @return Returns the new node's file information
|
||||||
|
* @throws FileExistsException
|
||||||
|
*/
|
||||||
|
@Auditable(key = Auditable.Key.ARG_0, parameters = {"parentNodeRef", "name", "typeQName"})
|
||||||
|
public FileInfo create(NodeRef parentNodeRef, String name, QName typeQName, QName assocQName) throws FileExistsException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete a file or folder
|
* Delete a file or folder
|
||||||
*
|
*
|
||||||
|
Reference in New Issue
Block a user