2

I am using the Java-API for Lotus Notes/Domino. I need to place Lotus-Documents inside auf Lotus-Folders (Views) which are organised like folders in the file system.

To find and optionaly create a folder I use the following code. The path-String uses the backslash separator (i.e. "TestFolder/SubFolder1/SubSubFolder1". The folders are created and displayed in the notes client as expected.

View view = database.getView(path);
if (view == null) {
    db.enableFolder(path);
    view = db.getView(path);
}

How can I find all subfolders of a specific folder?

Right now I am using this workaround. Imho this ist not very nice, because I am always reading ALL directories. When the structure gets larger, this will probably have an impact on the performance.

List<View> result = new ArrayList<View>();
String prefix = getPath() + getSeparator();
for (Object obj : database.getViews()) {
    View view = (View)obj;
    if (view.isFolder()) {
        String path = view.getName();
        if (path.startsWith(prefix)) {
            String suffix = path.substring(prefix.length());
            if (suffix.indexOf(getSeparator()) == -1) {
                result.add(view);
            }
        }
    }
}
christoph.keimel
  • 1,240
  • 10
  • 24
  • 1
    Subfolders aren't really subfolders. It is really just a flat structure with a naming convention that creates the illusion of subfolders, so the way you've coded it is appropriate. – Richard Schwartz Mar 26 '14 at 17:17

2 Answers2

4

Unfortunately there is no really fast way of doing this. If you really need performance, then the only way to make it a significantly faster is to work with NoteCollection- Class and get all folders. Then run through the NotesDocuments representing the folders and read the item "$Title". Here is example code of doing this:

NoteCollection nc = database.createNoteCollection(false);
nc.setSelectFolders(true);
nc.buildCollection();
String id = nc.getFirstNoteID();
while (id.length() > 0) {
  String strFolderName = ""
  Document docFolder = database.getDocumentByID(strFolderId);
  strFolderName = docFolder.getItemValueString("$Title");
  if (strFolderName.startsWith(prefix)) {
     ....
  }
}

In my tests this was factor 2-3 faster than using the getViews()- method.

Tode
  • 11,795
  • 18
  • 34
  • 2
    I agree it's far better to use NoteCollection, but there are a couple of problems here. First, you can use the SelectionFormula property to find the folders with the names that match your criteria. This saves you having to crack open each note as you scan your results, giving you more speed. Second, this code would incorrectly call "Georgia" a subfolder of "Geo". You would want names starting with "Geo\", not just "Geo". Note: when you use selectionformula, be careful to escape the special characters \ and " (doublequote) with an extra \. Folder name you're searching for might contain ". – Andre Guirard Mar 27 '14 at 14:46
  • @AndreGuirard How would you set the SelectionFormula to only return folders with a certain prefix? – christoph.keimel Jun 28 '17 at 12:50
0

The code in the OP is fine, except that the separator will always be "\" -- it's not dependent on the OS so there isn't a need for getSeparator call. You might also want to use a case-insensitive compare of the folder name, just in case.

It is LESS efficient to use a NoteCollection for this because it scans all the notes in the database, including all documents, whereas database.getViews uses the design collection to quickly narrow it down to just view notes.

It used to be inefficient to access the View object's properties just to see whether it's a view you're interested in, because it would update the view index. But in recent versions of Notes, that is no longer the case. No matter how many views you have, skimming thru the collection returned by getViews gives good performance.

Andre Guirard
  • 720
  • 4
  • 7