I access my database that has several fields:
rabbit2013
rabbit2014
rabbit2015
etc.
I am trying to create a program in Java to read the variable of the current year (rabbit2015 here). I have the current year in my variable year. How do I return the value of "rabbit"+year?
I tried this but doesn't work:
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("js");
Object result = null;
try {
result = engine.eval("rabbit"+year);
}
catch (ScriptException e){
e.printStackTrace();
}
System.out.println(result);
Have you got any ideas?
EDIT:
Error : ReferenceError: "rabbit2015" is not defined in <eval> at line number 1
result = engine.eval("\"rabbit\"+year");
The way you had it, Java was evaluating "rabbit"+year, then passing that to the eval method.
Assuming "year" is a java variable, you'll also need to put it on the ScriptEngine binding...
Bindings bindings = engine.createBindings();
bindings.put("year", year);
Then you pass the bindings in as a second parameter when you call eval()...
result = engine.eval("\"rabbit\"+year", bindings);
I find the answer of my question :
PS : When i talk you about rabits, it were examples, here it's "aRealiserEn"+year
I think I was not well enough explained my problem (promiss i will do better next). I thank all the same people who took time to read me and answer me (especially Phil Anderson and Biffen).
Related
tl;dr:
How do/can I store the function-handles of multiple js-functions in java for using them later? Currently I have two ideas:
Create multipe ScriptEngine instances, each containing one loaded function. Store them in a map by column, multiple entries per column in a list. Looks like a big overhead depending on how 'heavy' a ScriptEngine instance is...
Some Javascript solution to append methods of the same target field to an array. Dont know yet how to access that from the java-side, but also dont like it. Would like to keep the script files as stupid as possible.
var test1 = test1 || [];
test1.push(function(input) { return ""; });
???
Ideas or suggestions?
Tell me more:
I have a project where I have a directory containing script files (javascript, expecting more than hundred files, will grow in future). Those script files are named like: test1;toupper.js, test1;trim.js and test2;capitalize.js. The name before the semicolon is the column/field that the script will be process and the part after the semicolon is a human readable description what the file does (simplified example). So in this example there are two scripts that will be assigned to the "test1" column and one script to the "test2" column. The js-function template basically looks like:
function process(input) { return ""; };
My idea is, to load (and evaluate/compile) all script files at server-startup and then use the loaded functions by column when they are needed. So far, so good.
I can load/evaluate a single function with the following code. Example uses GraalVM, but should be reproducable with other languages too.
final ScriptEngine engine = new ScriptEngineManager().getEngineByName("graal.js");
final Invocable invocable = (Invocable) engine;
engine.eval("function process(arg) { return arg.toUpperCase(); };");
var rr0 = invocable.invokeFunction("process", "abc123xyz"); // rr0 = ABC123XYZ
But when I load/evaluate the next function with the same name, the previous one will be overwritten - logically, since its the same function name.
engine.eval("function process(arg) { return arg + 'test'; };");
var rr1 = invocable.invokeFunction("process", "abc123xyz"); // rr1 = abc123xyztest
This is how I would do it.
The recommended way to use Graal.js is via the polyglot API: https://www.graalvm.org/reference-manual/embed-languages/
Not the same probably would work with the ScriptEngine API, but here's the example using the polyglot API.
Wrap the function definition in ()
return the functions to Java
Not pictured, but you probably build a map from the column name to a list of functions to invoke on it.
Call the functions on the data.
import org.graalvm.polyglot.*;
import org.graalvm.polyglot.proxy.*;
public class HelloPolyglot {
public static void main(String[] args) {
System.out.println("Hello Java!");
try (Context context = Context.create()) {
Value toUpperCase = context.eval("js", "(function process(arg) { return arg.toUpperCase(); })");
Value concatTest = context.eval("js", "(function process(arg) { return arg + 'test'; })");
String text = "HelloWorld";
text = toUpperCase.execute(text).asString();
text = concatTest.execute(text).asString();
System.out.println(text);
}
}
}
Now, Value.execute() returns a Value, which I for simplicity coerce to a Java String with asString(), but you don't have to do that and you can operate on Value (here's the API for Value: https://www.graalvm.org/sdk/javadoc/org/graalvm/polyglot/Value.html).
I have an object in Groovy and in this object there appears to be either a map. I am trying to get the "value" rather than the key from this objects map. How do I go about doing something like this?
This is the output I am receiving in my console the first is the object and the 2nd is the output for the property fromValues...
<com.atlassian.jira.issue.changehistory.ChangeHistoryItem#b791639b id=10130 changeGroupId=10113 userKey=Charley field=status projectId=10000 issueId=10217 issueKey=ICB-128 created=2019-03-12 14:19:22.0 nextChangeCreated=292278994-08-17 02:12:55.807 fromValues=[10003:To Do] toValues=[3:In Progress]>
[runner.ScriptRunnerImpl]: 10003
Here is my code below that I am working with so far in attempt to get this information: (Just so you understand the context... I am pulling an issue from Jira software and extracting the history of that particular issue.)
IssueManager issueManager = ComponentAccessor.getIssueManager();
def issue = issueManager.getIssueObject("ICB-128");
def changeHistoryManager = ComponentAccessor.getChangeHistoryManager()
def changeItems = changeHistoryManager.getAllChangeItems(issue)
//def changeItems = changeHistoryManager.getChangeHistoriesSince(issue, since)
changeItems.eachWithIndex { item, index ->
//log.warn(changeItems.dump())
def last_change = changeItems[index]
log.warn(last_change.dump())
def text = "LAST MODIFIED FIELD:"+ last_change["field"] + "; FROM VALUE:"+ last_change["fromValue"] + "; TO VALUE:"+ last_change["toValue"]
if (last_change["fromValue"])
{
log.warn(last_change["fromValue"])
}
}
Edit 1: I have corrected for what #vahid suggested and now have both values returned how I want it. I have tried numerous ways to call and retrieve specifically the value for that map and nothing has worked (.get or .value or even .key)... Any suggestions?
Edit 2: Turns out this extracted field is now considered as a type "hashmap"
I have written a project that calculates different functions like sine,MCM etc without using existing packages like math in java
now I want to get an expression from the user in form of a string and then print out the result
like :
import java.util.Scanner;
public class Phase2main {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
String expression ;
double result = 0 ;
System.out.println(" Enter your desired expression from the available functions ");
expression = s.nextLine();
System.out.println("Result is : " + result);
}
}
then it should run like this:
Enter an Expression: ADD(DIV(SIN(FACT(3)),CEIL(TAN(MUL(1.5,FIB(4))))),GCD(2,10))
The Result is: 1.94
how can I make the program to identify my functions like CEIL and their input ?
I've checked many of the similar questions but the ones that I found are rather libraries that are too complex for me to understand or do basic arithmetic without identifying functions and their inputs
so how can I write a simple evaluator for this specific problem?
May be use JavaScript interpreter?
First create engine instance and init:
// Manager creates engines by mime/language names.
// It has own global scope for engiges created by it.
ScriptEngineManager manager = new ScriptEngineManager();
// Create JavaScript interpreter instance.
// (Nashorn is bundled JavaScript interpreter)
ScriptEngine scope = manager.getEngineByName("JavaScript");
// Define functions you need
String initialScript = "cos = Math.cos;" // ; or \n
+ "sin = Math.sin;"
+ "tg = Math.tan;"
+ "PI = Math.PI;"
// Any other function
+ "ctg = function (x) { return cos(x)/sin(x); };";
// ...
try {
// Add these functions to scope
scope.eval(initialScript);
} catch(ScriptException ex) {
// Evaluating exceptions, syntax errors are thrown here
}
And then you can evaluate expressions in the "scope" many times:
try {
double d = (double)scope.eval("sin(PI/2) + cos(PI/2)");
System.out.println("Calculated: " + d);
} catch(ScriptException e) {
// ...
}
Be warned:
There is language interpreting - user can pass any script and...
... it can reduce perfomance of application.
You can also use, for example, Jython or JRuby as interpreter.
You could use the Java Scripting API, and for instance use JavaScript, or BeanShell (java like).
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByMimeType("text/javascript");
try {
engine.eval("print('Result: ' + java.lang.Math.sin(0.8))");
double y = ((Number) engine.eval("java.lang.Math.sin(0.8)")).doubleValue();
} catch (ScriptException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
}
JavaScript can use imports. As you can see, calling java is quite simple.
I'm not sure if there is any simple way to identify and evaluate generic inputed expressions without using libraries.
If you want to develop your own way to evaluate math expressions take a look on this page, it should show you the way to go: http://cogitolearning.co.uk/?p=565
And if you change your mind and want to use an library, check this link: Evaluating a math expression given in string form
I've done this when I built a java compiler, that way I could read and evaluate any expression, but it wasn't simple...
I have the following code that defines a getParts method to find a given Part Name and Part Number in the system. Note that this code comes from our system's API, so if no one can help I'll just delete this question. I figured someone could potentially see a solution or help me along the way.
<%! private QueryResult getParts( String name, String number )
throws WTException, WTPropertyVetoException {
Class cname = wt.part.WTPart.class;
QuerySpec qs = new QuerySpec(cname);
QueryResult qr = null;
qs.appendWhere
(new SearchCondition(cname,
"master>name",
SearchCondition.EQUAL,
name,
false));
qs.appendAnd();
qs.appendWhere
(new SearchCondition(cname,
"master>number",
SearchCondition.EQUAL,
number,
false));
qr = PersistenceHelper.manager.find(qs);
System.out.println("...found: " + qr.size());
return qr;
}
%>
But I would like to allow the user more flexibility in finding these parts. So I set up conditional statements to check for a radio button. This allows them to search by part name and part number, find all, or search using a wildcard. However, I'm having trouble implementing the two latter options.
To attempt to accomplish the above, I have written the below code:
<%
String partName = request.getParameter("nameInput");
String partNumber = request.getParameter("numberInput");
String searchMethod = request.getParameter("selection");
//out.print(searchMethod);
QueryResult myResult = new QueryResult();
if(searchMethod.equals("search"))
myResult = getParts(partName, partNumber);
else if(searchMethod.equals("all"))
{
//Should I write a new function and do this?
//myResult = getAllParts();
//or is there a way I could use a for each loop to accomplish this?
}
//else if(searchMethod.equals("wildcard"))
//get parts matching %wildcard%
while(myResult.hasMoreElements())
{
out.print(myResult.nextElement().toString());
}
%>
Basically, it accepts user input and checks what type of search they would like to perform. Is there an easy way to pass all the values into the myResult object? And likewise for the wildcard search? Like I said before, it may be futile trying to help without access to the API, but hopefully it isn't.
Thanks!
You can (and should) reuse the function, but in order to do so, you will need a part name and number (as those are its input parameters). So for the multi-result options you will need to get a list/collection of part names+numbers and feed them individually to the function, then collect the result in the format that is most appropriate for your needs
User submits a CSV file which is consumed by a program. Values which are used throughout the program come from the CSV, natually if values are missed it is a problem. Below is my solution.
Ip on top
private List<String> currentFieldName = new ArrayList<String>();
As part of the method:
try {
setCurrentFieldName("Trim Space");
p.setTrimSpace(currentLineArray[dc.getTRIM_POSITION()].equals("yes") ? true : false);
setCurrentFieldName("Ignore Case");
p.setIgnoreCase(currentLineArray[dc.getIGNORE_CASE_POSITION()].equals("yes") ? true : false);
} catch (NullPointerException e) {
throw new InputSpreadsheetValueUnassignedException("\"Type\" field not set: " + currentFieldName);
}
And the method which keeps track of a current field being looked at:
private void setCurrentFieldName(String fieldName) {
currentFieldName.clear();
currentFieldName.add(fieldName);
}
The idea there is that if user fails to submit value and i will end up getting null, before throwing an exception, i will know what value was not assigned.
So, this being said, specific questions:
Is what i have shown below an acceptable solution?
Can you suggest something more elegant?
First thing that comes to my mind is that using an ArrayList to represent the name of a single field is superfluous.
Why not just define a private String currentFieldName; and inside your try { } do currentFieldName = "Trim Space" etc?
Also,
p.setTrimSpace(currentLineArray[index].equals("yes") ? true : false);
can just as well be expressed as
p.setTrimSpace(currentLineArray[index].equals("yes"));
If your code goes through many columns, you could definitely make it more elegant. If not, your time might be better spent on other parts of your project.
The answer to whether or not your solution is acceptable depends on the requirements, and a test suite would be the ideal party to provide the yes or the no.