(5);
}
public void setNamespaceService(NamespaceService namespaceService)
@@ -149,6 +151,22 @@ public class FileFolderServiceImpl implements FileFolderService
this.mimetypeService = mimetypeService;
}
+ /**
+ * Set the namespaces that should be treated as 'system' namespaces.
+ *
+ * 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 cm:name value.
+ *
+ * @param systemNamespaces a list of system namespaces
+ */
+ public void setSystemNamespaces(List systemNamespaces)
+ {
+ this.systemNamespaces.addAll(systemNamespaces);
+ }
+
// TODO: Replace this with a more formal means of identifying "system" folders (i.e. aspect or UUID)
public void setSystemPaths(List systemPaths)
{
@@ -572,8 +590,9 @@ public class FileFolderServiceImpl implements FileFolderService
}
}
+ QName existingQName = assocRef.getQName();
QName qname;
- if (nameChanged)
+ if (nameChanged && !systemNamespaces.contains(existingQName.getNamespaceURI()))
{
// Change the localname to match the new name
qname = QName.createQName(
@@ -583,9 +602,7 @@ public class FileFolderServiceImpl implements FileFolderService
else
{
// Keep the localname
- qname = QName.createQName(
- assocRef.getQName().getNamespaceURI(),
- assocRef.getQName().getLocalName());
+ qname = existingQName;
}
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
+ {
+ 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
boolean isFolder = false;
@@ -738,16 +765,19 @@ public class FileFolderServiceImpl implements FileFolderService
}
// create the node
- QName qname = QName.createQName(
- NamespaceService.CONTENT_MODEL_1_0_URI,
- QName.createValidLocalName(name));
+ if (assocQName == null)
+ {
+ assocQName = QName.createQName(
+ NamespaceService.CONTENT_MODEL_1_0_URI,
+ QName.createValidLocalName(name));
+ }
ChildAssociationRef assocRef = null;
try
{
assocRef = nodeService.createNode(
parentNodeRef,
ContentModel.ASSOC_CONTAINS,
- qname,
+ assocQName,
typeQName,
properties);
}
diff --git a/source/java/org/alfresco/repo/model/filefolder/FileFolderServiceImplTest.java b/source/java/org/alfresco/repo/model/filefolder/FileFolderServiceImplTest.java
index dbda9fba3c..981f0951c6 100644
--- a/source/java/org/alfresco/repo/model/filefolder/FileFolderServiceImplTest.java
+++ b/source/java/org/alfresco/repo/model/filefolder/FileFolderServiceImplTest.java
@@ -299,6 +299,35 @@ public class FileFolderServiceImplTest extends TestCase
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
{
FileInfo folderInfo = getByName(NAME_L0_FOLDER_A, true);
diff --git a/source/java/org/alfresco/service/cmr/model/FileFolderService.java b/source/java/org/alfresco/service/cmr/model/FileFolderService.java
index c7936af746..d1ed8156f5 100644
--- a/source/java/org/alfresco/service/cmr/model/FileFolderService.java
+++ b/source/java/org/alfresco/service/cmr/model/FileFolderService.java
@@ -169,18 +169,37 @@ public interface FileFolderService
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.
+ *
+ * The association QName for the patch defaults to cm:filename i.e. the
+ * Content Model namespace with the filename as the local name.
*
* @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 typeQName the type to create
* @return Returns the new node's file information
* @throws FileExistsException
+ *
+ * @see {@link #create(NodeRef, String, QName, QName)}
*/
@Auditable(key = Auditable.Key.ARG_0, parameters = {"parentNodeRef", "name", "typeQName"})
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 null).
+ * @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
*