<< Using the IBM Connections API from other languages using custom certificates | Home | Controlling the feature install location >>

The easy way to loop an XPage managed bean

I got harassed by Nathan (hmmm his blog appears to be down just now) yesterday for not contributing to the XPages dicussions out there so I thought I'd better remedy that. A quick tip is to make sure your Managed Bean implements Iterable if it contains a list of "things" and the obvious behaviour would be to loop over these things. If you implement Iterable you simple loop on the object using the "new" for-loop (when in Java) instead of first returning a List or array and then looping that with a for- or while loop.

Below is an example of a Managed Bean (just a Java-element from 8.5.3) that implements Iterable and hence it implements the iterator() method. That method should return an Iterator for the data you want to expose. Here I just return an iterator to the underlying list.

package com.example;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import lotus.domino.Database;
import lotus.domino.Document;
import lotus.domino.Session;
import lotus.domino.View;

import com.ibm.domino.xsp.module.nsf.NotesContext;

public class PeopleLister implements Iterable {
  // declarations
  private List people = new LinkedList();
  
  public PeopleLister() {
    NotesContext ctx = NotesContext.getCurrent();
    Session session = ctx.getCurrentSession();
    try {
      Database db = session.getDatabase(null, "names.nsf");
      View view = db.getView("People");
      Document doc = view.getFirstDocument();
      while (null != doc) {
        this.people.add(doc.getItemValue("FullName")
          .elementAt(0).toString());
        Document docTemp = view.getNextDocument(doc);
        doc.recycle();
        doc = docTemp;
      }
    } catch (Throwable t) {
      
    }
  }
  
  public Iterator iterator() {
    return this.people.iterator();
  }

  public String toString() {
    StringBuilder b = 
      new StringBuilder(this.people.size() * 25);
    for (String p : this) {
      if (b.length() > 0) b.append(',').append(' ');
      b.append(p);
    }
    return b.toString();
  }
  
  public String[] getList() {
    return (String[]) people
      .toArray(new String[people.size()]);
  }
}

With that in mind I can just use the bean as follows from SSJS code (e.g. a Label):

var people = new com.example.PeopleLister();
var result = "";
for (p in people) {
  if (result.length() > 0) result += ", ";
  result += p;
}
return result;
Happy coding!



Avatar: Sean Haggerty

loop in a managed bean

I am dense.

While I do see the  "<span class="pln">iterator</span><span class="pun">()</span>"  call, but what calls that function iterator() ?

When the function interator()  is called what is returned ?

And where is the returned result used?

*What would the code look like  -without-   "<span class="kwd">implements</span><span class="pln"> </span><span class="typ">Iterable</span><span class="pln"> </span><span class="pun">{"</span>  ?

I am reallllly mising something here.  Thank you for your patience.

SHaggerty

Avatar: Mikkel Flindt Heisterberg

loop in a managed bean

 You're thinking too muc - do not worry about it :) It is all hidden using the new glorified for-loop that was added in a recent Java release which allows you to loop any class implementing an interface ("exhibiting a known behaviour") called Iterable. When you implement this interface (or use a class that does) you have to have an iterator() method on the object which is what the for-loop ends up using. So doing something like 

 

for (p in people) {
  // do stuff the p from people...
}

is actually the same as writing

for (ite=people.iterator(); ite.hasNext(); ) {
  var p = ite.next();
  // do stuff the p from people...
}

or 

var ite = people.iterator();
while (ite.hasNext()) {
  var p = ite.next();
  // do stuff the p from people...
}

It's just easier when the compiler does it for you plus it means that you can make things easily iterable even though they are not a collection per say.

Hope it clarifies.

Avatar: Patrick Kwinten

Re: The easy way to loop an XPage managed bean

 I get the error message:

Description<span class="Apple-tab-span" style="white-space: pre;"> </span>Resource<span class="Apple-tab-span" style="white-space: pre;"> </span>Path<span class="Apple-tab-span" style="white-space: pre;"> </span>Location<span class="Apple-tab-span" style="white-space: pre;"> </span>Type

<div>Type mismatch: cannot convert from element type Object to String<span class="Apple-tab-span" style="white-space:pre"> </span>PersonList.java<span class="Apple-tab-span" style="white-space:pre"> </span>Picklist.nsf/Code/Java/com/example<span class="Apple-tab-span" style="white-space:pre"> </span>line 49<span class="Apple-tab-span" style="white-space:pre"> </span>Java Problem</div> <div> </div> <div>-> for (String p : this) {</div>

Add a comment Send a TrackBack