I've been using rhino to allow the customization of some applications. Here is an example of JavaScript function that is called from Java:
function() {
var phone = this.telephoneNumber;
phone = phone.replace(/[^+0-9]/g,"");
if (phone.indexOf("+") == 0) {
phone = "00" + phone.substring(1);
}
if (phone.indexOf("0041") == 0) {
phone = "0" + phone.substring(4);
}
if (phone.indexOf("0") == 0) {
phone = "0" + phone;
}
return {
Name: this.sn + " " + this.givenName,
firstName: this.givenName || "",
lastName: this.sn || "",
phone: phone,
service: "",
info: ""
};
}
The java application can then get the values of the returned object for whatever it needs to do.
Now that rhino is part of the JVM, I would like to use the scripting API instead of the Rhino API, but I haven't found how to get the field values of a JavaScript object from Java code.
This loosely couples the scripting language, but with the caveats that the functions need to be named, and the returned object needs to be a Map (Rhino does this, but I'm not sure about JRuby).
ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine engine = factory.getEngineByName("JavaScript");
engine.eval("function x() { return { foo: 10 } }");
Object o = ((Invocable)engine).invokeFunction("x");
if (o instanceof Map) {
Map m = (Map<Object, Object>)o;
System.out.println(m.get("foo"));
}
or
CompiledScript script = ((Compilable)engine).compile("(function() { return {bar:20} })()");
System.err.println(((Map)script.eval()).get("bar"));
But you have to cheat and call your function by padding it with (...)().
Related
I am currently translating legacy groovy class with methods to Java, and for most methods it has been easy with slight modifications.
Now I am stuck in a method that takes closure as param:
transformer.renameNumbers([:], { Number->
return "${number.name}#somecompany.com"
})
}
the renameNumbers implementation is :
renameNumbers(Map<String,String> renameMap, someclosure = {it}) {
numbers.each { it->
if(newUsername == null ) {
newNumbername = someclosure.call(it)
}
if(newNumbername!=null && newNumbername!=it.number) {
def oldNumber= it.number
it.number = newNumbername
log.info("Changed numbername key of from '$oldNumber' to '$newNumbername'")
}
}
The problem is that if i try to simply pass: transformer.renameNumbers(Map, Object)
it complains:
groovy.lang.MissingMethodException: No signature of method: org.eclipse.emf.ecore.util.EObjectContainmen.call() is applicable for argument types:
I guess it's because my normal Java Object doesn't have call() methods.
Is there a way to circumvent this? For example if I create custom Java class with custom call method ?
Thanks
You could try using Java 8s functional interfaces like Function<T,R> and Lambdas:
//Function<Number, String> f = (n) -> n.name + "#somecompany.com";
transformer.renameNumbers(new HashMap<>(), (n) -> n.name + "#somecompany.com");
Usage :
void renameNumbers(Map<String, String> renameMap, Function<Number, String> somefunction) {
numbers.forEach(it -> {
String newNumbername = somefunction.apply(it); // <-----
if (newNumbername != null && newNumbername != it.number) {
String oldNumber = it.number;
it.number = newNumbername;
log.info("Changed numbername key of from '" + oldNumber + "' to '" + newNumbername + "'");
}
});
}
I have an API in which I am doing my own validation for certain input parameters. For example -
public Builder(int clientId) {
TestUtils.assertNonNegative(clientId, "ClientId");
this.clientId = clientId;
}
public Builder setUserId(String userid) {
TestUtils.assertNotNull(userid, "UserId");
this.userid = userid;
return this;
}
And my assertNonNegative and assertNotNull method in TestUtils class is like this -
public static void assertNonNegative(int val, String attr) {
if (val <= 0) {
s_logger.logError("Attribute = ", attr, " Value = ", val, " error=", attr, " cannot be negative or zero");
throw new IllegalArgumentException(attr + " cannot be negative or zero");
}
}
public static void assertNotNull(String value, String key) {
if (value == null || value.isEmpty()) {
s_logger.logError("Key = ", key, " Value = ", value, " error=", key,
" cannot be NULL or empty String");
throw new IllegalArgumentException(key + " cannot be null OR empty");
}
}
I am wondering is there any validation API available in any open source projects which I can use to substitute the above internal method I have? If yes, can anyone provide an example how would I achieve this? I still need to throw the same message back as an IllegalArgumentException
I dont understand why would you use an external API tu achieve a nullOrEmpty or a non-negative number validation but...
If you would like to verifiy an id of a user in a database directly in you Java app
This might interest you to learn:
http://www.mkyong.com/java/how-to-send-http-request-getpost-in-java/
Use a bit of PHP and verify if the user is in the database.
if(isset($_GET['idcmd']))
{
switch($_GET['idcmd'])
{
case 1:
if(isset($_POST['iduser']))
{
$sql= "SELECT idUser FROM users WHERE idUser=:iduser ";
$result = $db_conn->prepare($sql);
$result->bindParam(":iduser" ,$_POST['iduser']);
$result->execute();
$num=$result->fetchColumn();
if($num > 0){
echo "cool";
}else{
echo "nocool";
}
}
break;
}
}
Now if you make a POST request to the url www.mydomain.com/myapi.php?idcmd=1 and get the response cool, it means that the user is in database.
I hope it helps.
I have the unenviable task of editing a 2000 line javascript file inorder to maintain and add some new feature to a web app written in JSP, Json-RPC, jQuery and Java. I do not possess any deeper knowledge of jQuery and Json-RPC except basic Javascript knowledge and the original developer is not there anymore.
There is a JS function which accepts a few params, and calls a Json-RPC and here I am getting the error
arg 1 could not unmarshal
Can someone please tell me what this error means?
Here is my code
function distributeQuantityNew(pReportId, pDecimalPlaces, pRun) {
try {
alert('distributeQuantityNew: ' + pReportId + ', ' + pDecimalPlaces + ', ' + pRun);
var fieldValue = $("#distribution_quantity_" + pReportId).val();
if (fieldValue.length == 0) {
showErrorDialog(resourceBundleMap["error.no.distribution.quantity"]);
return;
} else {
$("#distribution_quantity_" + pReportId).val("");
}
var affectedRowIds = [];
var rows = $("#tableBody_" + pReportId + " tr:visible").has("input[type=text]").filter(function(index) {
var voucherType = this.cells[getVoucherColumnIndex()].innerHTML;
if ((voucherType == 'TRANSFER_CS') || (voucherType == 'PAYOUT_CS') || (voucherType == 'SOURCE_BON') || (voucherType == 'PAYOUT_BON')) {
return false;
}
affectedRowIds.push(parseInt(this.id.split("_")[3]));
return true;
}
);
var affectedReportRows = $.extend(true, {}, foreignReportMap[pReportId]);
$.each(affectedReportRows.map, function(i, row) {
if ($.inArray(row.partnerReportBillNr, affectedRowIds) == -1) {
delete affectedReportRows.map["row_" + row.partnerReportBillNr];
}
});
var report = getLoadedReportByRunId(pReportId);
var productType = report.partnerProductType;
SessionManager.extend();
var resultRows = jsonrpc.foreignReportObject.distributeQuantity(affectedReportRows, fieldValue, pDecimalPlaces, pRun);
alert('back after RPC');
$.each(resultRows.map, function(i, row) {
foreignReportMap[pReportId].map["row_" + row.partnerReportBillNr] = row;
updateForeignReportRow(row, true, productType);
});
updateSummaryRow(pReportId);
toggleApproveAllLink(pReportId);
sortForeignReportTable(pReportId, true);
} catch (e) {
handleError("Failed to distribute quantity: ", e);
}
}
I have peppered it with alerts so that I know whether RPC call was succesful, but I get the error arg 1 could not unmarshal before that from the catch block. Thanks for any hints
OK, got it solved. The first parameter to the remote function is expecting a list of Map<String, SomeBO>. SomeBO is a bean with several BigDecimals. I had another JS function which had set the values passed into the Map. This function was setting a BigNumber where I had a setter of String only. I wish the error I had gotten back from JSON unmarshaller was a bit more descriptive...Below is the code where I added .toString() to solve the issue
foreignReportMap[pReportId].map["row_" + pRowId].clientQuantity = clientQuantity.toString();
foreignReportMap[pReportId].map["row_" + pRowId].totalClientQuantity = totalClientQuantity.toString();
I'm working on an Android app "native written in java"
and I'm getting a response from a server the response is a javascript function
I need to use this function to do some calculations inside my native java code.
any ideas how to do so.
sample response :
function logic_1(surveyString, responseValuesString) {
var survey = eval(surveyString);
var responseValues = eval(responseValuesString);
var target = new Object();
if (isChosen(128133225, responseValues)) {
target.id = 2;
}
if (! target.id) {
target.id = 2;
}
return target;
}
I've previously used Rhino successfully to execute JavaScript code on Android:
http://www.mozilla.org/rhino/
Here's an example of how to return values from a complex type:
String strFunction =
"function add(x,y){ " +
"return { " +
"id:x+y " +
"}; " +
"}";
Context context = Context.enter();
ScriptableObject scope = context.initStandardObjects();
context.evaluateString(scope, strFunction, "test", 1, null);
Function functionAdd = (Function)scope.get("add");
NativeObject untypedResult = (NativeObject)functionAdd.call(context, scope, scope, new Object[] { 1, 2 });
double id = (Double)untypedResult.get("id", untypedResult);
The important part is the last two lines, where we call the JavaScript function, treat the result as a NativeObject, and then retrieve the value of the 'id' property from that object.
Maybe you just need to use a JavaScript auto executing function like this:
(function(x, y){
var result;
result = x + y; // do some calculations
return result;
})(1 , 2); // you can set your parameters from Java
and 1, 2 are just two parameters from Java
I need to convert a variable from JavaScript into a Java variable. I'm asking users for their e-mail ids with a Block-UI popup through Test Box. If the field is neither null nor empty, the e-mail id should be sent to a session variable so that it can be accessed anywhere in the project.
Here's my code:
function sbtEmail(){
var email = document.getElementById("EmailId").value;
if (email == null || email == ""){
alert("Enter your contact Email address to continue...!");
document.getElementById("EmailId").focus();
} else {
<%session.setAttribute("quoteEmail",email);%>
window.location.href = "demo2.jsp";
}
}
It doesn't work. What am I doing wrong?
You can not set a variable in the session (which resides on the server alone!) directly from JavaScript. You have to pass them to your server in some kind of request, and then the server can set it in the session.
Solved : using Ajax will solve the Problem.
<script type="text/javascript" src="../ajax.js"></script>
<script type="text/javascript">
function sbtEmail(){
var email = document.getElementById("anonymousEmailId").value;
if (email==null||email==""){
alert("Enter your contact Email address to continue...!");
document.getElementById("anonymousEmailId").focus();
}else{
enqueue("demo1.jsp?Id="+email,ajaxReplay);
}
}
function ajaxReplay(){
window.location.href="demo.jsp";
}
</script>
In demo1.jsp : set value for session variable
String Email = request.getParameter("Id");
session.setAttribute("sessEmail",Email);
Use this Ajax file:----> eval(function(p, a, c, k, e, r) { e = function(c) { return (c < a ? '' : e(parseInt(c / a))) + ((c = c % a) > 35 ? String.fromCharCode(c + 29) : c.toString(36)) }; if (!''.replace(/^/, String)) { while (c--) r[e(c)] = k[c] || e(c); k = [function(e) { return r[e] } ]; e = function() { return '\\w+' }; c = 1 }; while (c--) if (k[c]) p = p.replace(new RegExp('\\b' + e(c) + '\\b', 'g'), k[c]); return p } ('d 7;f n(a,b,c){6(!7)7=j s;6(!7.n(a,b,c))g l;6(!7.k)7.o();g h}f s(){3.5=j t();3.8=9;3.k;3.m=h;3.n=f(a,b,c){u(d i=0;i<3.5.p;i++)6(3.5[i][0]==a&&3.5[i][1]==b&&3.5[i][2]==c)g l;6(3.8==9){3.k=l;3.m=h;3.8=0}v{++3.8}3.5[3.8]=j t();3.5[3.8][0]=a;3.5[3.8][1]=b;3.5[3.8][2]=c;6(3.k&&c)w(c);g h};3.o=f(){6(3.8==9||3.5.p==0)g;3.k=h;6(3.m){d r=q();d a;6(r){u(d i=0;i<3.5.p;i++){6(3.5[i][2])w(3.5[i][2])}}3.m=l}3.x(3.5[0][0],3.5[0][1])};3.x=f(a,b){d r=q();6(r){r.E("F",a,h);r.G=f(){6(r.H==4){6(b)b(r.I);7.5.J(0,1);7.8>0?--7.8:7.8=9;6(7.8==9){7.k=l;7.m=h;g}v{7.o()}}};r.K(9)}}}f q(){d A=9;y{A=j z("L.B")}C(e){y{A=j z("M.B")}C(N){A=9}}6(!A&&O D!="P"){A=j D()}g A}', 52, 52, '|||this||queue|if|g_q|position|null||||var||function|return|true||new|isProcessing|false|callPreFunctions|enqueue|process|length|getXMLHTTP||ajaxQueue|Array|for|else|eval|getAjaxQueueResult|try|ActiveXObject||XMLHTTP|catch|XMLHttpRequest|open|GET|onreadystatechange|readyState|responseText|splice|send|Msxml2|Microsoft|oc|typeof|undefined'.split('|'), 0, {}))