Search code examples
javaxpagesmanaged-bean

Xpages: How to ensure my cacheBean only loads once


Still struggling with properly making a cacheBean. I think I want the bean to be a singleton, from what I have read. Will only need one instance of it. Use it to get often used keywords and so on.

http://blog.defrog.nl/2013/02/prefered-way-for-referencing-beans-from.html

I used this pattern to make my CacheBean (and used a utility method).

If I make this a managedBean by putting it into Faces-config, then I can easily get the value of models

<xp:text escape="true" id="computedField1"          
value="#{CacheBean.models}"></xp:text>

The JSF takes care of instantiating the bean for me.

But I don't want it to reload the same values (like models) over and over. I thought that to get that to happen I needed to make a POJO and grab the currentInstance of the bean, as in the url.

However, when I made this change (taking the bean out of the faces-config file, I cannot seem to get a handle on the properties.

This won't even compile:

<xp:text escape="true" id="computedField1"
        value="#{Cache.getCurrentInstance().models}">
    </xp:text>

What am I doing wrong?

================================

package com.scoular.cache;

import java.io.Serializable;
import org.openntf.domino.xsp.XspOpenLogUtil;

import com.scoular.Utils;

public class CacheBean implements Serializable {

    private static final long serialVersionUID = -2665922853615670023L;
    public static final String BEAN_NAME = "CacheBean";

    private String pcDataDBpath;

    private Vector<Object> models = new Vector<Object>();


    public CacheBean() {
         initConfigData();
    }

    private void initConfigData() {
        try {
      loadModels();
      loadDBPaths();
        } catch (Exception e) {
            XspOpenLogUtil.logError(e);
        }
    }


    // Getters and Setters

    public static CacheBean getInstance(String beanName) {
        return (CacheBean) Utils.getVariableValue(beanName);
    }

    public static CacheBean getInstance() {
        return getInstance(BEAN_NAME);

    }

    public String getPcDataDBpath() {
        return pcDataDBpath;
    }

    public void setPcDataDBpath(String pcDataDBpath) {
        this.pcDataDBpath = pcDataDBpath;
    }

    public void loadDBPaths() {

        Session session = Factory.getSession();
        Database tmpDB = session.getCurrentDatabase();

        pcAppDBpath = (tmpDB.getServer() + "!!" + "scoApps\\PC\\PCApp.nsf");
        pcDataDBpath = (tmpDB.getServer() + "!!" + "scoApps\\PC\\PCData.nsf");
        compDirDBpath = (tmpDB.getServer() + "!!" + "compdir.nsf");
    }

    public void loadModels() {
        try {
            Session session = Factory.getSession();
            Database tmpDB = session.getCurrentDatabase();
            Database PCDataDB = session.getDatabase(tmpDB.getServer(), "scoApps\\PC\\PCData.nsf");
            ViewNavigator vn = PCDataDB.getView("dbLookupModels").createViewNav();
            ViewEntry entry = vn.getFirst();
            while (entry != null) {
                Vector<Object> thisCat = entry.getColumnValues();
                if (entry.isCategory()) {
                    String thisCatString = thisCat.elementAt(0).toString();
                    models.addElement(thisCatString);
                }
                entry = vn.getNextCategory();
            }
        } catch (Exception e) {
            XspOpenLogUtil.logError(e);
        }
    }

p

ackage com.scoular;

import javax.faces.context.FacesContext;

public class Utils {

      public static Object getVariableValue(String varName) {
            FacesContext context = FacesContext.getCurrentInstance();
            return context.getApplication().getVariableResolver().resolveVariable(context, varName);
          }
}

Solution

  • When the bean has the right scope you can access the bean directly if is created.

    private static final String BEAN_NAME = "CacheBean";
    
    //access to the bean
        public static CacheBean get() {
                return (CacheBean) JSFUtil.resolveVariable(BEAN_NAME);
        }
    
    //in my JSFUtil class I have the method
    public static Object resolveVariable(String variable) {
            return FacesContext.getCurrentInstance().getApplication().getVariableResolver().resolveVariable(FacesContext.getCurrentInstance(), variable);
        }
    

    so in a Java Class you can call

    CacheBean.get().models
    

    in EL you can use

    CacheBean.models