How to pass a JavaScript array to an XPages Java Controller - java

I'm working with jQuery DataTables. I have it listing out a view and have checkboxes to select multiple documents. I'm able to get the selected keys into session scope via this client side JavaScript code :
<xp:this.script><![CDATA[// Build array of selected rows
var myTableApi = x$("inventoryTable").DataTable();
var count = myTableApi.rows( { selected: true } ).count();
var dataArr = [];
var rowData = myTableApi.rows( { selected: true } ).data();
$.each($(rowData),function(key,value){
dataArr.push(value[3]);
});
// Push that to the requestScope
setScopeValue("session", "rowCount", count);
setScopeValue("session", "rowIds", dataArr);]]></xp:this.script>
Once the id's are in Scope I change pages and then I want to load them into my Java pageController.
I can easily use a variable resolver to get ahold of "rowIds". But I'm not sure how to get it into Java so I could work with it. Ideally I'd like it to be List or Set or something similar.
In Java, how can I convert this JavaScript Array to a Collection based object?
Thanks!

There are a few tricks to do here.
First, since the particular implementation of your setScopeValue function converts all values to a string before sending them to the server, it's important to do setScopeValue("session", "rowIds", XSP.toJson(dataArr)). That way, the value stored on the server will be ["foo", "bar", "baz"] instead of foobarbaz.
Secondly, the best way to get to the session-scoped value in Java would be via ExtLibUtil.getSessionScope().get("rowIds").
That value will be a string, though, and not an array type, so it'll have to be parsed from JSON. Using the IBM Commons JSON capabilities, that can be done with:
List<?> rowIds = (List<?>)JsonParser.fromJson(JsonJavaFactory.instance, ExtLibUtil.getSessionScope().get("rowIds"))
for(Object rowIdObj : rowIds) {
String rowId = StringUtil.toString(rowIdObj);
// do stuff with each ID here
}
You can also potentially case it directly to a List<String>, since Java's generics are really just hints for compiler-generated code, and not really enforced in the objects themselves, but there you run the risk of a ClassCastException if the incoming List contains any non-string types.

Related

Can't convert Apigee Java Object response to string

I'm using the GetAPIProduct policy (see http://apigee.com/docs/gateway-services/content/retrieve-api-product-settings-using-getapiproduct
) to get a list of scopes. Then in a JavaScript callout, I try to reference that list of scopes, but instead of text I get back something like this (the hex chunk at the end changes with each call):
[Ljava.lang.String;#19baa7ed
There doesn't seem to be anything I can do to turn it into an array I can access using Javascript. I'm in a Free org so Java is not an option. I've tried String(), myvar.toString() and even the Rhino context.javaToJs which doesn't seem to exist in Apigee.
Any ideas how I can either convert this to a string?
It turns out that the value of getapiproduct.{policyname}.apiproduct.scopes is a zero-based array of objects. Each of those objects, though, can be converted to a string that is a scope name.
So here's how you access the array of scopes:
var scopeArray=context.getVariable("getapiproduct.RetrieveProductInfo.apiproduct.scopes");
// you can use either of these methods to convert the array elements
var firstElement = String(scopeArray[0]);
var secondElement = scopeArray[1]+'';
var scopeArrayLen = scopeArray.length;
This isn't an answer to the question, but is some additional information that may be valuable.
The GetAPIPRoductInfo gets the list of scopes on a product. Conversely, the GetOAuthV2Info policy gets information about an OAUthV2 token. Assuming you have a token you could do something like this:
<GetOAuthV2Info name='GetOAuthV2Info-TokenScopes'>
<!-- use one of the following: a referenced variable or -->
<!-- an explicitly passed access_token -->
<AccessToken ref='access_token'/>
<!--
On Success, the following flow variables will be set.
oauthv2accesstoken.{policy_name}.access_token
oauthv2accesstoken.{policy_name}.scope
oauthv2accesstoken.{policy_name}.refresh_token
oauthv2accesstoken.{policy_name}.accesstoken.{custom_attribute_name}
oauthv2accesstoken.{policy_name}.developer.id
oauthv2accesstoken.{policy_name}.developer.app.name
oauthv2accesstoken.{policy_name}.expires_in
oauthv2accesstoken.{policy_name}.status
-->
</GetOAuthV2Info>
Then you can use that information in a subsequent JS callout to check the scopes for the token against whatever requirement you have:
// checkScope.js
// ------------------------------------------------------------------
var varname = 'oauthv2accesstoken.GetOAuthV2Info-TokenScopes.scope',
approvedScopes = context.getVariable(varname),
check = false;
approvedScopes = approvedScopes.split(' ');
// approvedScopes is now a JavaScript array of strings, that lists
// the scopes the user approved for the requesting client (app).
//
// You can now compare that list against the scopes required
// for an operation or resource, and then set a variable
// determining whether the token is good for the request.
context.setVariable('scopeCheck.ok', check);

Java Code to fetch Session Store attribute values

I am writing an Assertion Generator Plugin in Java to fetch a user details from Session Store and modify the values in Assertion(SAML 2.0) accordingly.
I am able to identify the method(Link) using which I can pull the user values from Session Store (agentAPIObject.getSessionVariables()) based on SessionID, but, I am having trouble writing a code to fetch specific parameters from the session store. (speficially around setting values for Attribute method and making it as an array)
Can someone post a sample code if you have ever seen/written around it, so that I can fetch user attributes from Session Store.
I am having trouble understanding Java docs around it.
Thanks in advance,
The API mentions this:
responseAttributeList - On successful return from this method (YES is
returned), this output parameter contains the retrieved variable names
and their values. If the method returns UNRESOLVED, this parameter
includes variables that could not be retrieved.
You'll need to create two AttributeList Objects. If the response of getSessionVariables(...) is YES, then the variable responseAttributeList will contain the session variables. Since Java uses references, that same variable responseAttributeList will be updated. You can then use getAttributeAt(...) to access the Attribute Objects.
String sessionID = "sampleID";
ResourceContextDef rcd = //whatever it needs to be equal to
AttributeList requestAttributeList = new AttributeList();
AttributeList responseAttributeList = new AttributeList();
if(getSessionVariables(sessionId, rcd, requestAttributeList, responseAttributeList) == YES){
Attribute att = responseAttributeList.getAttributeAt(0);//or whatever index.
}
Remember to carefully read the API.
NOTE: This is just pseudo code. I have not tested this. However, this should be plenty enough to get you going where you need to.

java web service wsdl: Getting data out of a responce variable

Very new to web services (as you can tell from the Q) so i am pretty sure this is a basic question.
I am sending the request of to the server
ExecuteSQLQueryReq sqlParams = new ExecuteSQLQueryReq();
sqlParams.setSql(sqlState.getNoDevInDP("LIV_Phones_DP"));
and getting the response i expect:
ExecuteSQLQueryRes getSqlResult = axlPort.executeSQLQuery(sqlParams);
i can see all the data is there in the object from the eclipse debugging
but from the object "getSqlResult" i dont know how to pull the data out. The response is in the following format:
Any help would be great
Thanks
Alexis
EDIT:
Screen shot of "ExecuteSQLQueryRes". The only methods i see is to return a list of Objects, which i do and that the screenshot of the variables in eclipse you mention. Its the next step .... how to get from a generic Object the data out..
From the type signatures, I'd say you would invoke the service like so:
List<Object> rows = axlPort.executeSQLQuery(sqlParams)
.getReturn()
.getRow();
for(Object row : rows) {
Element rowElement = (Element) row;
// utilize DOM API
}
As far as I can tell from the information posted you're getting a List of Elements. In XML:
<row>?</row>
<row>?</row>
<row>?</row>
Since row is anyType nothing specific can be inferred about its structure. In the specific case, the first entry looks like this assuming a single child (text) node:
<row>339</row>
You can use the Java DOM APIs to access the data.
From the name onwards, this service looks like it just exposes the underlying database implementation. Consider adhering to stricter SOA principles if you have any influence over the service design.

how to read a list of objects from the configuration file in play framework

How can i read a list of users from the configuration file in play framework?
i have tried doing something like this:
users=[{uid:123,pwd:xyz},{uid:321,pwd:abc}]
from the play application
List<Object> uids = Play.application().configuration().getList("users");
will give me this a list of objects, if I iterate through the list i get each object as
{uid=123,pwd=xyz} and {uid=321,pwd=abc}
at this point i don't know how i can elegantly get the value of the uid, i can do some hacky job as omit the first and last bracket and parse for the before after equal sign, but it would be too ugly! any idea? (the application is written in java)
thanks
A Scala implementation that avoids the deprecated getConfigList method would rely on retrieving a Seq[Configuration] as follows:
case class UserConfig(uid: Int, pwd: String)
val userConfigs: Seq[UserConfig] = configuration.get[Seq[Configuration]]("users").map { userConfig =>
UserConfig(userConfig.get[Int]("uid"), userConfig.get[String]("pwd"))
}
Since I had recently the same problem and this is still unanswered,
here is my suggestion:
List<User> users = getConfig().getConfigList("users").stream().map(
config -> new User(config.getString("uid"), config.getBoolean("pwd"))
).collect(Collectors.toList());
As far as I know there are no tuples or anything in Java, you need to use either an object or a list with two elements. I decided to go for an object here, you can also return a list.
A list of uid's sounds to me like:
# List of UID's
users=[123,456,789] // every number represents a UID
Then you can get this list as:
List<Object> uids = Play.application().configuration().getList("users");
And then do what you want with this:
for (Iterator<Object> iterator = uids.iterator(); iterator.hasNext();) {
Object object = (Object) iterator.next();
System.out.println(object);
}
Is this what you are looking for?
BTW, you can read more about Play Framework configuration options: http://www.playframework.com/documentation/2.1.0/Configuration

Passing a DataTable object from JavaScript to Java

I am using the Google Visualization API on the client side and I create a DataTable object. Then I want to pass it to my server and upload it via the Spreadsheet API to a spreadsheet. Probably the best way is to use JSON, so I converted it with the method toJSON() and sent it over POST to my server. I tried to use these 2 classes:
DataTable (JavaScript)
DataTable (Java)
Now I noticed, that these 2 classes aren't compatible, at least not over JSON. The JavaScript class converts for example to this:
{"cols":[
{"id":"Col1","label":"","type":"string"}
{"id":"Col2","label":"","type":"date"}
],
"rows":[
{"c":[{"v":"a"},{"v":"Date(2010,10,6)"}]},
{"c":[{"v":"b"},{"v":"Date(2010,10,7)"}]}
]
}
But the Java side DataTable has different names for the parameters, and I am using Gson which has different type values:
cols -> columns
c -> cells
v -> value
type:"string" -> type:"TEXT"
type:"number" -> type:"NUMBER"
And I am afraid that there are even more incompatibilities.
So.. how can I convert the JavaScript DataTable to the Java object DataTable?
I ran into the same problem in reverse. It appears that the DataTable object in the Java Datasource Library is not parallel to the Javascript DataTable object in the Google Visualization API.
Returning a Java Datasource Library DataTable object requires using the JsonRenderer, rather than the default serialization. And it appears only to work passing from the server to the client. Am not sure if it can be done the other direction.
#WebService
#Path("/tables")
public class DataManager extends GenericManager<db, Long> {
#Path("/hello/")
#GET
#Produces(MediaType.APPLICATION_JSON)
public DataTable getDataTable() {
DataTable data = new DataTable();
... populate object ...
return data;
}
However, the Java DataTable object returned by default serialization is not the same thing as the Google Visualization API javascript DataTable. You can't pass it to a GVis chart.
Instead, from Java, you use the JsonRenderer class (see this Google Groups email) to convert it to a Json-like string that's missing quotes around attributes for modest compression.
#Path("/hello/")
#GET
#Produces(MediaType.TEXT_PLAIN)
public String getDataTable() {
DataTable data = new DataTable();
CharSequence charSequence = JsonRenderer.renderDataTable(dataTable, true, true);
return charSequence.toString();
}
That string can be parsed in Javascript by surrounding with parentheses, not shown in the object literal notation in the examples (see this Google Group forum):
jQuery.ajax({
context: this,
type: 'Get',
url: url,
success: function(data) {
var args = eval('('+data+')'); // add parens around the returned string
var dataTable = new google.visualization.DataTable(args);
...
});
I don't see a method for going the reverse way to the Java Datasource Library DataTable object.
So not quite an answer but you're not alone
Well I am using python on the backend and GWT on the frontend and passing a DataTable from the backend to the frontend works without any problems.
I am using the google-visualization-python api on the backend to create the DataTable.
Parsing is done with following code:
DataTable dataTable = DataTable.create(JSONParser.parseLenient(data).isObject().getJavaScriptObject());
I also convert the parsed DataTable back to JSON to store the json string in localStorage and parsing the stored json string also works fine.
The GWT DataTable is just a simple wrapper which ultimately just calls the function of the underlying Javascript DataTable via JSNI.So I don't see any reason why they should be incompatible.
Make sure you use the latest gwt-visualization API (1.1.2) ?

Categories