package com.eric.test; import javax.faces.context.ExternalContext; import javax.faces.context.FacesContext; import javax.faces.context.ResponseWriter; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Map; import lotus.domino.*; import com.ibm.xsp.model.domino.DominoUtils; import com.google.gson.JsonArray; import com.google.gson.JsonObject; /** * Data provider Class with a single, public, static method * to provide an XAgent micro-service, returning formatted * data as application/json. * * @author Eric McCormick, @edm00se * src: http://edm00se.github.io/DevBlog/xpages/custom-JSON-with-Java-sized-XAgent * */ public class DataProvider { /** * This method performs some sample actions against * a Domino View's Documents, reads them into a * JsonArray, attaches it to the JsonObject response * and returns it as a data response via FacesContext. * This should be invoked as part of an XAgent. * * @return JsonObject sample response * @throws IOException */ public static void GetMyDataAsJson() throws IOException{ //initialize the main JsonObject for the response JsonObject myData = new JsonObject(); /* * Here we're establishing our external context handle, * where we get our response writer from. */ FacesContext ctx = FacesContext.getCurrentInstance(); ExternalContext exCon = ctx.getExternalContext(); /* * Using a response writer is one way of directly dumping into the response. * Instead, I'm returning the JsonObject. */ ResponseWriter writer = ctx.getResponseWriter(); HttpServletResponse response = (HttpServletResponse) exCon.getResponse(); //set my content type, use a robust character encoding, and don't cache my response response.setContentType("application/json"); response.setHeader("Cache-Control", "no-cache"); response.setCharacterEncoding("utf-8"); try { /* * This is how we can get a handle on and use any URL parameters * instead of the Domino SSJS param handle. Note that I check * for the existence of the the parameter of myKey before assigning * it, via ternary operator. */ Map<String,Object> exConP = exCon.getRequestParameterMap(); String myParam = (exConP.containsKey("myKey")) ? exConP.get("myKey").toString() : null; /* * Using the Domino Session class, we can get a handle on our current * session and interact with anything via the Java NotesDomino API. */ Session s = DominoUtils.getCurrentSession(); Database db = s.getCurrentDatabase(); View vw = db.getView("GoTCharFlat"); /* * perform any necessary business logic with the data */ //creating an array of objects JsonArray dataAr = new JsonArray(); /* * This is an example only as there are easier ways to * get a JSON response of a View; e.g.- Domino Data/Access Services. */ Document first = vw.getFirstDocument(); //simple View iteration of documents and adding of a given value while(first!=null){ //creates current object JsonObject curOb = new JsonObject(); String name = first.getItemValueString("CharFullName_FL"); String title = first.getItemValueString("Title"); curOb.addProperty("name", name); curOb.addProperty("title", title); //adds current object into JsonArray dataAr.add(curOb); //no OpenNTF Domino API implemented, ham fist away! Document tmpDoc = vw.getNextDocument(first); first.recycle(); first = tmpDoc; } //wrap it up and add the JsonArray of JsonObjects to the main object myData.add("data", dataAr); /* * Business logic done, setting error to false last, so * if anything errors out, we'll catch it. */ myData.addProperty("error", false); }catch(Exception e){ /* * On error, sets a boolean error value of true * and adds the message into the errorMessage * property. */ myData.addProperty("error", true); myData.addProperty("errorMessage", e.toString()); System.out.println("Error with data provision method:"); System.out.println(e.toString()); } /* * This will always return a fully formed JsonObject response. * Meaning that if there's an error, we hear about it and can * handle that on the client side for display while developing, * or logging when in production. * * Note: since we're hijacking the FacesContext response, we're * returning a string (not data object) into the ResponseWriter. * This is why the method is void. Don't worry, it's application/json. */ writer.write(myData.toString()); } }