Dynamic Generation Of IF Statements For Concatenation - java

I'm looking for a flexible/generic way to build up conditions using metadata stored in a Database and then validate incoming requests at runtime
against the conditions and concatenate value(s) if the condition is met.
My use case looks something like this:
1) A business user selects an operation from a UI i.e. (IF condition from a dropdown), then selects an appropraite field to evaluate i.e. ("language")
then selects a value for the condition i.e. "Java" followed by some values to concatenate i.e "Java 9" and "is coming soon!"
2) This metaData will get stored in a Database (lets say as a List for the moment) i.e ["language","Java","Java 9","is coming soon"]
When my application starts I want to build the appropriate concatenation conditions:
private String concatenateString(String condition, String conditionValue, String concatValue1, String concatValue2){
StringBuilder sb = new StringBuilder();
if (condition.equals(conditionValue)){
sb.append(concatValue1);
sb.append(concatValue2);
}
return sb.toString();
}
3) so at runtime when I receieve a request, i want to compare the values on my incoming request to the various conditions that got built at start up:
if language == "Java" then the output would look like => "Java 9 is coming soon"
While the above might work for 2 String concatenations, how can achieve the same for a variable number of conditions and concatenation values.

So you want user to create a program by selecting options from a GUI which will be stored in a DB. When the options are read back from the DB you want to parse this into a compileable program and run it?
Use StringBuilder to build a string of the code from the data gotten back from the DB, something like this:
"if (language == '"Java"') { doSomething() }" (you'll need to take care to escape strings inside your string if you are storing strings in the DB.
You can then use Compiler class to compile the string to a program which yo can run (all in runtime, google dynamically compiling c# at runtime).
However, you'll probably want to question why you are thinking of going down that route... I've been there before, dynamic compilation has a very narrow use case.
You could, for instance, create a Dictionary which maps selected languages to some output string and simply use this to get your output like:
Dictionary<string, string> langaugeOutputMap = new Dictionary<string, string>();
languageOutputMap.Put("Java", "Java9 is coming soon");
private string concatString(string: userChosenString) {
if (languageOutputMap.containsKey(userChosenString) {
return languageOutputMap.getValue(userChosenString);
}
return string.Empty()
}
If you then want to manage multiple conditions, you could have multiple Dictionaries for each condition type and enumerate them in a collection, iterate over them when given a variable sized set of conditions and make sure that all the conditions evaluate through the use of containsKey().
Also, you can use params to specify variable length function arguments like so:
public string manyArgs(params string[] stringArgs) {
}
Also, look at PredicateBuilder:
http://www.albahari.com/nutshell/predicatebuilder.aspx

Related

How to verify/compare 2 values in Selenium?

I have an input file which contains some String values. Lets Say String one.
On a web page, I am identifying a web element and getting its value as a String. lets say String two.
String one = "abc" //Value from input file.
String two = "USabc" // Value from identifying a web element.
I have to compare these 2 strings and my test case is that String two should contain "US" as well as contents of String one which are "abc"
How can i do this ?
Also, if I have multiple inputs and multiple outputs in one script, whats the best way of doing this?
To compare the presence of the text within the variable one as well as the text US within the variable two you can use the following solution:
if(two.contains(one) && two.contains("US"))
System.out.println("Comparision successful");
else
System.out.println("Comparision unsuccessful");
Selenium Assertions are the best way you can use Assert to compare two values.
Assertions verify that the state of the application is same to what we are expecting. Selenium Assertions can be of three types: “assert”, “verify”, and ” waitFor”. When an “assert” fails, the test is aborted. When a “verify” fails, the test will continue execution, logging the failure.
Available in
import org.testng.Assert;
and perform
Assert.assertEquals("one","two");
If you do not want your test to fail at a particular assertion and want to continue till the end and then assert, you can use SoftAsserts
You can read more about that here https://www.seleniumeasy.com/testng-tutorials/soft-asserts-in-testng-example

Most efficient way to check string array and then write it into file

I need to check a List of Strings to contain certain predefined strings and - in case all these predefined string are contained into the list - I need to write the list to a File.
As a first approach I thought to do something like
if(doesTheListContainPredefinedStrings(list))
writeListIntoFile(list);
Where the doesTheListContainPredefinedStrings and writeListIntoFile executes loops to check for the prefefinedStrings and to write every element of the list to a file, respectively.
But - since in this case I have to worry about performance - I wanted to leverage the fact that in the doesTheListContainPredefinedStrings method I'm still evaluating the elements of the list once.
I also thought about something like
String[] predefinedStrings = {...};
...
PrintWriter pw = new FileWriter("fileName");
int predefinedStringsFound = 0;
for (String string : list)
{
if (predefinedStrings.contains(string))
predefinedStringsFound++;
pw.println(string);
}
if (predefinedStringsFound == predefinedStrings.length)
pw.close();
Since I observed that - at least on the system where I'm developing (Ubuntu 19.04) - if I don't close the stream the strings aren't written to the file.
Nevertheless, this solution seems really bad and the file would still be created, so - if the list wouldn't pass the check - I'd have the problem to delete it (which requires another access to the storage) anyway.
Someone could suggest me a better/the best approach to this and explain why it is better/the best to me?
check the reverse case — is any string from predefs in the strings-to-check-list missing?
Collection<String> predefs; // Your certain predefined strings
List<String> list; // Your list of strings to check
if( ! predefs.parallelStream().anyMatch( s -> ! list.contains( s ) ) )
writeListIntoFile(list);
The above lambda expression stops as soon as the first string from predefs can't be found in the strings-to-check-list and returns true — You must not write the file in this case.
It does not check if any additional strings are in the strings-to-check-list, that are not contained in the predefs strings.

Deserialize server response

I'm wondering if is the way to deserialize the server response. So in my case I have an LinkedHashMap<String,Date> and returing this from server:
#Override
public LinkedHashMap<String, Date> testHMap() {
LinkedHashMap<String, Date> map = new LinkedHashMap<>();
map.put("AA", new Date());
map.put("BB", new Date());
return map;
}
I'm trying to get info about another application(gwt) so I can perform calls only via HTTP, and from upper example the HTTP response looks like : //OK['WM577vZ',4,5,2,'WM577vZ',4,3,2,2,0,1,["java.util.LinkedHashMap/3008245022","java.lang.String/2004016611","AA","java.util.Date/3385151746","BB"],0,7]
So, is there a way to get the LinkedHashMap data from this HTTP respone?
The LinkedHashMap is in that response - that response is an object stream (i.e. instead of JSON, if the same value appears twice, it will only be serialized once, which lets the content be smaller, and also allows cyclical references instead of only a flat tree).
Reading the RPC payload is done "backward" - starting from the end and reading backward, we start with 7 (the version), 0 (the flags that are set), a big [] of strings (the "string table", the strings that are needed to decode the reply, so that each string is only listed once).
Then a 1 - the first object in the stream is the type of the first entry in the string table, i.e. "java.util.LinkedHashMap/3008245022" as you are looking for. To decode a LinkedHashMap, we first need to know how it is ordered - the next 0 value tells us that it uses the default of "insertion-order", and then the next 2 says that there are two entries in the map.
Now we iterate until we've seen the two pairs of keys and values. The next value will tell us what kind of key we're looking at: 2 means to go into the string table and we see "java.lang.String/2004016611", so we know it will be a string, then the 3 shows us "AA" also from the string table. Next is 4, the type of the value for that key, predictably this "java.util.Date/3385151746" from the string table. To deserialize a date, we read a long from the payload - GWT base64-encodes these to keep them smaller - this is 'WM577vZ', the next token.
The next 4 tokens, (2, 5, 4, and 'WM577vZ') repeat this process, adding the second string key to the map, and the date value for it.
--
This particular payload isn't the kind that really shows RPC's power, but it is fairly simple to read by hand. Decoding them outside of a GWT app is currently not very easy (though I'm working on a generalized tool which should let it be decoded anywhere, but a SO answer isn't really the place to talk about it) - if you want a format that can be handled by plain JS or some other non-GWT technology, RPC likely isn't your best bet at this time.
I think you are looking for something like restyGWT.
But I don't really understand your question so I might be wrong.

Better way to interpret user text input

I have a Text Box in my app and the user can input anything. I am creating a controller which interprets some of the commands based on the keywords.
The user has an option of either setting a password or not. And depending on that, my interpreter will either expect a password or not.
For example, if a Password is set and user enters: "password1 show list".
The interpreter checks for password in the first word, then next for the command(show) and then the argument(list).
If password not set, user enters "show list" and the interpreter understands.
My current code is:
// 'words' is a String array which contains the user input.
if (passwordEnabled()==true) {
if (words[0].contentEquals(getPassword())
&& words[1].contentEquals("show")
&& words[2].contentEquals("list")) {
// Perform action
}
}
else {
if (words[0].contentEquals("show")
&& words[1].contentEquals("list")) {
// Perform action
}
}
My question is, is there a more efficient/better way to process commands? I am sure mine is a very crude method of doing it.
Your way (or any grammar-based approach) is OK if users can remember the syntax of the commands.
If you want to understand the users when they express their intent with unrestricted, natural language, you need to do some Natural Language Understanding.
Something like Wit (http://wit.ai) may do the job for you. It's based on machine learning. It converts free text sentences into JSON with the user intent and normalized parameters.
If you are trying to design the "language" based system, where you ask commands, you should think about two possible approaches based on the system complexity:
building the finite automa of your system. Your if statements are the very basic form of such structure, but definind this as an actual automa, where you have states, and commands that moves you to the another state - is a very clean and generic approach.
building a grammar + interpreter/compiler. Defining correct commands as grammatical (+compiler) rules would give you much more power in expressing possible commands and actions.
Of course these are not alternating solutions - building a grammar for the language is a very broad thing, and should be used to parse the command, while finite state automa serves as the internal memory and the definition of possible actions.
Building a grammar or finite automa are right ways of doing that, agreed.
If you want an easy way, you may simplify your code like that:
if (passwordEnabled()) {
if (! words.get(0).contentEquals(getPassword()))
{
// wrong password
return;
}
words.remove(0); // skip password
}
if (words.get(0).contentEquals("show")
&& words.get(1).contentEquals("list")) {
// Perform action
}
Suppose you use ArrayList for words.

Manipulating Strings on Arrays

I'm still new to Java and I would like to understand Strings and Arrays so I got this idea of manipulating elements and place them according to my objective. The objective is that there will be Array of Strings "ABBCCCBBAA" and the "AA","BB" must be replaced into "A" , "BA","AB" into CC. "CC","BC" into B. I basically have no idea how to make it happen but I know it must have Arrays of String. Please help
Regular expression can be very handy for you. Code bellow can do, your job with the use of regular expression:
String mainStr = "ABBCCCBBAA";
Pattern p = Pattern.compile("(AA)|(BB)|(BA)|(AB)|(CC)|(BC)");
Matcher m = p.matcher(mainStr);
while (m.find()) {
String matchedStr = m.group(0);
if("AA".equals(matchedStr) || "BB".equals(matchedStr)){
mainStr = mainStr.replaceFirst(matchedStr,"X");
}
else if("BA".equals(matchedStr) || "AB".equals(matchedStr)){
mainStr = mainStr.replaceFirst(matchedStr,"Y");
}
else if("CC".equals(matchedStr) || "BC".equals(matchedStr)){
mainStr = mainStr.replaceFirst(matchedStr,"Z");
}
}
mainStr = mainStr.replaceAll("X","A").replaceAll("Y","CC").replaceAll("Z","B");
System.out.println(mainStr);
Above code will handle your case of multiple occurrence of same pattern in a given string like:
ABBCCCBBAABBBBAA
will generate output:
CCBBAAAAA.
I am assuming that by "array of strings" you mean:
String[] myvariable = new String[number];
myvariable[0] = "ABBCCBBAA";
myvariable[1] = "some_other_string";
If you are new to Java I suggest you read a beginner's book like Head First Java and also look into java documentation; you don't even have to go that far if you are programming with a decent IDE, like Netbeans (thanks to its intelli-sense feature) is a source of documentation for what you seek (meaning that you can look at all the methods available for a string, read what they do, and see if they can help accomplish what you need).
I am assuming (from what you have said) that you want to replace "AA" for "A", and from that result replace "BB" for "BA", and from that result replace "AB" into "CC", and from that result "BC" into "B".
The code I am posting is REAL simple, and it will only work for this particular case (as I have understood it), if you want to create a method that does this for any string, you need to change some things, but I'll leave that to you.
String[] yourArrayOfStrings = new String[1];
yourArrayOfStrings[0] = "ABBCCBBAA";
String resultOfReplacement= yourArrayOfStrings[0].replaceFirst("AA", "A");
System.out.println(resultOfReplacement); //debugging purposes
resultOfReplacement = resultOfReplacement.replaceFirst("BB", "BA");
System.out.println(resultOfReplacement); //debugging purposes
resultOfReplacement = resultOfReplacement.replaceFirst("AB", "CC");
System.out.println(resultOfReplacement); //debugging purposes
resultOfReplacement = resultOfReplacement.replaceFirst("BC", "BB");
System.out.println(resultOfReplacement); //debugging purposes
The only reason why I created a String[] was because that's what you stated in your question, otherwise I would have simple created a String variable like I did with resultOfReplacement. To access the first element in an array you do arrayVariable[index]. Here I use the replaceFirst function that comes with Java for variables of type String. If you look the method up, it'll tell you that it will look for the first match of the first parameter and replace it with the second parameter.
The System.out.println I have added are for debugging purposes, so you can see on the console what is clearly happening with each replacement. So, the first time I call replaceFirst(...) on the original string which is a[0].
This will happen:
The method will look in "ABBCCBBAA" for the FIRST AND ONLY THE FIRST time "AA" appears and replace it with "A". The result is "return" and you must assign it to a variable if you want access to it to do more actions upon it. In this case, I assign it to a new String variable. You could have just assigned back to a[0], which is likely what you want. (You'd do so like this: a[0]=ourArrayOfStrings[0].replaceFirst("AA", "A");)
For the second replacement, the method will look in "ABBCCBBA" for the first time "BB" appears and replace it for "BA".
See the pattern? This is just a start, and depending on what you want you might need other methods like replaceAll().
Most IDEs will tell you what methods are available for a variable when you access it via ".", so that when you are typing " variablename. " right at that moment a list of methods available for it should appear, if they don´t you can go ahead and do a shortcut like ctrl+space for it to appear and navigate through the methods via the arrow keys so you can read what they do (at least for Eclpise and Netbeans, while programming in Java, it works). Documentation is power!

Categories