Ask Questions and Find Answers
Important:
Ask is now read-only. You can review any existing questions and answers, but not add anything new.
But - don't panic! While ask is no more, we've replaced it with discuss - the new Liferay Discussion Forum! Read more here here or just visit the site here:
discuss.liferay.com
Replacing invalid characters in file and folder names
Greetings:
For lots of good reasons, Document Library (DL) file and folder names are not allowed to contain invalid characters such as "[", "%", "#" and so on (see the full list in AssetUtil.INVALID_CHARACTERS). I have no wish to change this but since my customers have LOTS of files with such characters in the file names I'm working on a solution to substitute valid chacters (say, the underscore) for the invalid ones before they get added.
So far I've had great success handling bad file names using an ext plugin to override the addFileEntry method in DLFileEntryLocalServiceImpl and the addFolder method in DLFolderLocalServiceImpl. For example, when I add a file called bad%file.pdf to the DL, either through the UI or through WebDAV, it gets stored as bad_file.pdf and everything is fine. Similarly, Bad#Folder becomes Bad_Folder, again through either the UI or WebDAV.
But I've run into a situation where my overrides don't work and I'd appreciate some advice about how to solve it: when I try to add a folder STRUCTURE containing subfolders with some bad names through WebDAV (you can't do this through the UI) files can't get added tp the renamed folders. Here's a concrete example:
Structure:
Instead of getting the whole structure, what happens is that my WebDAV client throws an error and I wind up with this:
Notice that although Folder_Level2 was created (because I replaced the invalid characters), no files were added under it, not even goodfile1.txt.
I am assuming that the reason for this is that while I have fixed the folder name locally, that is, within the scope of the addFolder method, that change does not propagate upward to the class that actually invokes DLFolderLocalServiceImpl. So its got these files that it wants to add to a folder that it thinks is called Folder@Level2, but it can't find such a folder so it stops. This happens even though the DLFolder object returned by addFolder has the right name, as determined by folder.getName().
I have to somehow make the change in the folder name at a higher level, perhaps even in the WebDAVRequest, so that all subsequent methods use the valid name rather than the original one.
But I'm not sure where that would be.
Thanks, in advance, for any helpful comments.
Bruce
For lots of good reasons, Document Library (DL) file and folder names are not allowed to contain invalid characters such as "[", "%", "#" and so on (see the full list in AssetUtil.INVALID_CHARACTERS). I have no wish to change this but since my customers have LOTS of files with such characters in the file names I'm working on a solution to substitute valid chacters (say, the underscore) for the invalid ones before they get added.
So far I've had great success handling bad file names using an ext plugin to override the addFileEntry method in DLFileEntryLocalServiceImpl and the addFolder method in DLFolderLocalServiceImpl. For example, when I add a file called bad%file.pdf to the DL, either through the UI or through WebDAV, it gets stored as bad_file.pdf and everything is fine. Similarly, Bad#Folder becomes Bad_Folder, again through either the UI or WebDAV.
But I've run into a situation where my overrides don't work and I'd appreciate some advice about how to solve it: when I try to add a folder STRUCTURE containing subfolders with some bad names through WebDAV (you can't do this through the UI) files can't get added tp the renamed folders. Here's a concrete example:
Structure:
FolderLevel1
goodfile1.txt
bad%file1.pdf
/Folder@Level2
goodfile2.txt
bad%file2.pdf
Instead of getting the whole structure, what happens is that my WebDAV client throws an error and I wind up with this:
FolderLevel1
goodfile1.txt
bad_file1.pdf
/Folder_Level2
Notice that although Folder_Level2 was created (because I replaced the invalid characters), no files were added under it, not even goodfile1.txt.
I am assuming that the reason for this is that while I have fixed the folder name locally, that is, within the scope of the addFolder method, that change does not propagate upward to the class that actually invokes DLFolderLocalServiceImpl. So its got these files that it wants to add to a folder that it thinks is called Folder@Level2, but it can't find such a folder so it stops. This happens even though the DLFolder object returned by addFolder has the right name, as determined by folder.getName().
I have to somehow make the change in the folder name at a higher level, perhaps even in the WebDAVRequest, so that all subsequent methods use the valid name rather than the original one.
But I'm not sure where that would be.
Thanks, in advance, for any helpful comments.
Bruce
OK, I think I solved this. As I thought, the problem was much higher in the chain of classes used in the route to the DLFile and DLFolder service implementations. The class DLWebDAVStorageImple has methods for making collections (folders) and putting resources (files). It gets the information about file and folder names from the getPathArray method of WebDAVRequest, which is called for each file and folder name in the path. Applying my change (that replaces the invalid characters) for each element in the array, each time that information is fetched from the WebDAVRequet, prevents the issue I mentioned above.
Overriding DLWebDAVStorageImpl is done in liferay-portal-ext.xml.
Also, for what it's worth, I'll pass on a useful trick that a colleague of mine showed me that is extremely useful in finding all the classes touched on the way to a given point in the code. It not only helped me to find DLWebDAVStorageImpl, but also told me which methods I needed to override and verified that my subclass was the one being called. The trick is to deliberately throw an exception then examine the stacktrace. At any point in the code, add this:
See ya!
Bruce
Overriding DLWebDAVStorageImpl is done in liferay-portal-ext.xml.
Also, for what it's worth, I'll pass on a useful trick that a colleague of mine showed me that is extremely useful in finding all the classes touched on the way to a given point in the code. It not only helped me to find DLWebDAVStorageImpl, but also told me which methods I needed to override and verified that my subclass was the one being called. The trick is to deliberately throw an exception then examine the stacktrace. At any point in the code, add this:
try {
if (true) throw new Exception("Check your stacktrace.");
} catch (Exception e) {
e.printStackTrace();
}
See ya!
Bruce