1
votes

I posted part of this previously but thought I would start a new thread with a more complete code and problem. I am trying to walk through the categories in a NotesViewNavigator and this is the code that I am using. I have stripped it down to pretty much a minimum. The WFSUtils.sysOut just writes a message to the server console. The view has the "Do Not Display Empty categories" checked.

vw.setAutoUpdate(false);
var nav:NotesViewNavigator = vw.createViewNav();
nav.setEntryOptions(NotesViewNavigator.VN_ENTRYOPT_NOCOUNTDATA);
nav.setBufferMaxEntries(400);
nav.setMaxLevel(0);
var rtn:java.util.TreeMap=new java.util.TreeMap();
var entry:NotesViewEntry = nav.getFirst();
var thisCat:java.util.Vector = new java.util.Vector;
try{
while (entry != null){
    WFSUtils.sysOut("Entry not null");
    thisCat = entry.getColumnValues();
    var thisCatString = thisCat.elementAt(0).toString()
    WFSUtils.sysOut("thisCat = " + thisCatString);
    rtn.put(thisCatString,"Nothing");
    WFSUtils.sysOut("did put " + thisCatString)
    var tEntry:NotesViewEntry = nav.getNextCategory();
    entry.recycle();
    entry = tEntry;
    tEntry.recycle();
}
viewScope.put("vsCats", rtn.keySet());
}catch(e){
    WFSUtils.sysOut("Error in getCategory " + e.toString())
}

When I run this code I get the following in the server console.

25/08/2014 12:55:42 PM  HTTP JVM: Entry not null
25/08/2014 12:55:42 PM  HTTP JVM: thisCat = Approved~Bill Fox^WFS Automated Back end Process Example
25/08/2014 12:55:42 PM  HTTP JVM: did put Approved~Bill Fox^WFS Automated Back end Process Example
25/08/2014 12:55:42 PM  HTTP JVM: Error in getCategory Method NotesViewNavigator.getNextCategory(lotus.domino.local.ViewEntry) not found, or illegal parameters

It fails at the getNextCategory(entry) that it is not found or illegal parameter. If I change it to just getNext(entry) the console log shows:

25/08/2014 01:06:48 PM  HTTP JVM: Entry not null
25/08/2014 01:06:48 PM  HTTP JVM: thisCat = Approved~Bill Fox^WFS Automated Back end Process Example
25/08/2014 01:06:48 PM  HTTP JVM: did put Approved~Bill Fox^WFS Automated Back end Process Example
25/08/2014 01:06:48 PM  HTTP JVM: Entry not null
25/08/2014 01:06:48 PM  HTTP JVM: Error in getCategory Exception occurred calling method NotesViewEntry.getColumnValues()
25/08/2014 01:06:48 PM  HTTP JVM: null

So it would appear to me that the var entry is getting messed up somewhere along the line. Interesting is that the getFirst works and my code functions the way I would expect it but neither getNext nor getNextCategory seems to work. Am I missing something in my code or what the getNextCategory should be doing.

2
If you're only interested in getting a sorted list of categories, you might consider using a TreeSet instead of a TreeMap. Looks like you don't really need the map. And since the categories in a view are already sorted, you could also just use a List. - Mark Leusink
I thought of that but wanted to get it working first. Knut's answer fixed it for me, sometimes you can look so hard that you can't see. - Bill F
@Mark did you write the Application Scope document locking for Xpages? I got a copy of it but the person who sent it to me could not remember where it came from. It kind of looks like some of your type of code. Also, if it is your code is there a place to download it? - Bill F
That wasn't me. Might be this one: openntf.org/main.nsf/project.xsp?r=project/… - Mark Leusink
That does not appear to be it. - Bill F

2 Answers

2
votes

Delete the line

tEntry.recycle();

This recycle() destroys your entry as both entry and tEntry point to the same Notes object.

Delete the parameter from

... nav.getNextCategory();

Your code shown in question doesn't have a parameter but the error message and your comment tell you have.

0
votes

Here is what I have ended up with. What I need to do is create a series of nested Reapeat controls that function much like native Notes Categories. So the top level category is bound to a viewScope "vsCat1", the next to "vsCat2" and the last to "vsCat3" This process could be extended to handle more levels but I generally try to keep the number of categories below that. For this example the three categories are Status, Originator and Process. I have then built three views called vwDocsByStatus, vwDocsByStatusOrig, and vwDocsByStatusOrigProcess. The first column in each view is categorized. The byStatus view is simply a categorized view by Status, the StatusOrig is Status + "~" + Originator and the third Status + "~" + Originator + "~" + Process. The collection name for the first repeat is cat1, second cat2 and third cat3. My code below is a JavaScript function that I'm going to move to a JAVA Bean but the function would be the same. So to load "vsCat1" I would call setCategory("vwDocsByStatus",""), to load "vsCat2" I would call setCategory("vwDocsByStatusOrig", cat1) which would load vsCat2 with all of the categories under cat1. calling setCategory("vwDocsByStatusOrigProcess", cat1 + "~" + cat2) will load vsCat3 with all categories under the combination cat1 ~ cat2. The limitation is that there is no expand all type of action, but I have found that in most cases that is OK. Then in the final repeat it is bound to the domino view vwDocsByStatusOrigProcess and a computed filter on column of cat1 + "~" + cat2 + "~" + cat3 Each repeat has an expand/collapse button that sets some viewScope variables to control visibility and calls setCategory with the appropriate view and cat values. Faster method is to just get the column values from a view but that does not take into account reader fields so the return might have some category values that the user is not allowed to see. My testing this far is that this is pretty fast. Hope this helps someone, also if you can see how to improve it feel free to make suggestions

function setCategory(appView:String , cat:String){
    /*Given a categorized view retrieve the a list of values and store that
     * list in a viewScope variable "vsCat" + n where n = "1" if cat is null
     * if cat contains one "~" n = 2 if cat conatins two "~" n = 3
     * 
     */
    //get appDB and the view
    try{
        var vw:NotesView = appProps[sessionScope.ssApplication].appDB.getView(appView);
        vw.setAutoUpdate(false);
        var nav:NotesViewNavigator = vw.createViewNav();
        nav.setEntryOptions(NotesViewNavigator.VN_ENTRYOPT_NOCOUNTDATA);
        nav.setBufferMaxEntries(400);
        nav.setMaxLevel(0);
    }catch(e){
        WFSUtils.sysOut("Error in setCategory - " + e.toString());
        return "";
        break;
    }
    try{
        var rtn:java.util.TreeSet=new java.util.TreeSet();
        var entry:NotesViewEntry = nav.getFirst();
        if (cat.indexOf("~") > 0) {
            n = 3;
        }else if (cat == null || cat == ""){
            n = 1;
        }else  {
            n = 2;
        }
        var catArray:Array = cat.split("~");
        var thisCat:Array = new Array;
        while (entry != null && !entry.isTotal()) {
            thisCat = entry.getColumnValues();
            var temp:String = thisCat[0].toString();
            thisCat = temp.split("~");
            if (typeof thisCat === "string"){
                thisCat = [thisCat];
            }
            switch (n){
                case 1 :
                        if (!rtn.contains(thisCat[0])){
                            rtn.add(thisCat[0]);
                        }

                    break;
                case 2 :
                    if (cat == thisCat[0]){
                        if (thisCat[1] != null){
                            if (!rtn.contains(thisCat[1]))rtn.add(thisCat[1]);
                        }
                    }
                    break;
                case 3 :
                    if (cat == thisCat[0] + "~" + thisCat[1]){
                        if (thisCat[2] != null){
                            if (!rtn.contains(thisCat[2]))rtn.add(thisCat[2]);
                        }
                    }
                    break
            }

            var tmpentry:NotesViewEntry = nav.getNextCategory();
            entry.recycle();
           entry = tmpentry;
        }// end while
        // set the viewScope variable
        vw.setAutoUpdate(true);
        viewScope.put("vsCat" + n.toString(),rtn);
    }catch(e) {
        WFSUtils.sysOut("Error in setCategory - " + e.toString());
    }finally{
        try{
            WFSUtils.recycleObjects([nav, entry, tmpEntry]);
        }catch (e) {
            //do nothing caused by undefined object shouldn't happen
        }
    }
}