Saturday, December 17, 2011

Accessing XPages global objects in Java

Update 24-Dec-2011: Added method to access session and database.

Update 10-Mar-2012: Updated the view object as it was pointing to a super class. Thanks to Tom pointing that one out.

Update 22-May-2012: Rectified the code to get viewScope. Thanks to Jens Winkelmann for pointing it out.

Update 16-Mar-2013: Added link to get getComponent equivalent in Java.

Tim Tripcony in his reply to one of the questions in the Notes/Domino XPages development forum had suggested using Java over SSJS to improve XPages performance. He basically said – “...Minimize the use of SSJS (server-side JavaScript). Every time any SSJS expression is evaluated, Domino parses the expression in realtime into an abstract syntax tree, then runs Java code that is a rough approximation of how the JavaScript specification states that code matching the detected syntax should run. The more you move your logic directly into true Java classes, the less expensive it is to execute, so it runs faster...

So I started thinking about how can we access various XPages Global Objects like – facesContext, sessionScope, context, etc. from Java classes.


Well... here's how we can access it:


I have kept the names of the variables same as the XPages Global Objects. And yes... make sure you import the following classes to use the above code snippet:


You can explore the class DominoUtils as it also contains a lot more utility functions. I wasn't able to find any equivalent code for getComponent in Java so I raised this question of StackOverflow and got some ways to do it.

7 comments:

  1. COOL

    I tried to get to the XSP page name on which the java is running, but view.getPageName() does not exist....

    Any ideas?

    Tom

    ReplyDelete
    Replies
    1. I made a mistake up there! The code should be like this:

      UIViewRootEx2 view = (UIViewRootEx2)facesContext.getViewRoot();

      And import the class as:

      import com.ibm.xsp.component.UIViewRootEx2;

      This should do the trick. Thanks for pointing that out. I have update my post.

      Delete
  2. Hallo,

    I am trying to use some SSJS-Classes in a Java-Agent. My testing code is (it's most the same with your example):

    import javax.faces.context.FacesContext;
    import javax.faces.el.ValueBinding;
    import lotus.domino.*;

    public class JavaAgent extends AgentBase {
    public void NotesMain() {
    try {
    Session session = getSession();
    AgentContext agentContext = session.getAgentContex();

    ValueBinding vb = FacesContext.getCurrentInstance().getApplication().createValueBinding("#{javascript:getData()}");
    System.out.println(vb.getValue(FacesContext.getCurrentInstance()).toString());

    } catch(Exception e) {
    e.printStackTrace();
    }
    }
    }

    How can I resolve the "import javax.faces.context.FacesContext"? In Eclipse (Java-Perspective) I can let Eclipse to resolve this import, but after saving and reopening the agent, this import is again unresolved.

    Thank you for any ideas/help !!

    ReplyDelete
    Replies
    1. I am not sure if you can use the XPages class in Java Agents. The agent runs in its own JVM (i.e. different class loader). To use XPages classes like FacesContext you will have to import those JARs in your Java Agent (have never tried it before).

      Some time back I wanted to use same JAR file for both my XPages and Java Agents - but it turns out you can't. I posted my query on XPages forum:

      http://www-10.lotus.com/ldd/xpagesforum.nsf/topicThread.xsp?action=openDocument&documentId=E89573775690EC9C85257840001DC328

      May be this can give you a some hint.

      You may also ask the experts on XPages forum or Stackoverflow :)

      Delete
  3. Thank you very much for your answer! Yes, I didn't thought about that, that the agent is running in its own JVM - yes, of course, this makes sense.

    I found the solution to my issue by using XAgents (I have allready implemented it - and it works fine). And of course the "right solution" is to port all the SSSJ to Java... But I must find the time for this :-)

    Greetings from Germany
    Adrian

    ReplyDelete
  4. This is wrong:
    Map viewScope = facesContext.getViewRoot().getViewScope();
    Use getViewMap instead of getViewScope.
    Map viewScope = facesContext.getViewRoot().getViewMap();

    ReplyDelete
    Replies
    1. Thanks Jens for pointing that one out. I have updated my post. :)

      Delete