I am building tests in SoapUI. I have a very large response (>3500 duties). For that response I need to build a request and execute that request. Currently the code (Java) works, but I would like to optimize the code.
For each Duty I build a request to get additional employee data and execute it using a for next loop. Below is an example of the large XML response that I get.
<DUTIES>
<DUTY>
<EMPNO>1</EMPNO>
<LOCATION>AMS</BASE_STATION>
<ACTUALTIME>2019-02-20T06:00:00</ACTUALTIME>
<POSITIONING_CODE>1</POSITIONING_CODE>
</DUTY>
<DUTY>
<EMPNO>2</EMPNO>
<LOCATION>RTM</BASE_STATION>
<ACTUALTIME>2019-02-20T06:00:00</ACTUALTIME>
<POSITIONING_CODE/>
</DUTY>
<DUTY>
<EMPNO>1</EMPNO>
<LOCATION>AMS</BASE_STATION>
<ACTUALTIME>2019-02-21T06:00:00</ACTUALTIME>
<POSITIONING_CODE>1</POSITIONING_CODE>
</DUTY>
</DUTIES>
As you can see from the sample the same employee is multiple times in the response, so currently I am calling the request multiple time for the same employee. I would like to optimize this.
In SoapUI I can use the statement:
String[] emps = resp.getNodeValues("/Duties/Duty/string(EMPNO)");
String[] locs = resp.getNodeValues("/Duties/Duty/string(LOCATION)");
String[] tims = resp.getNodeValues("/Duties/Duty/string(ACTUALTIME)");
Then I would like to sort the arrays on emps and only build a request to get additional employee data when the employee changes. This will make the code much faster.
Now my questions:
What is the best way to do this? Work with multidimensional array and sort them? Or is there a better way of doing this?
Thanks in advance,
Said
I would create an instance of java.util.HashMap<String,String> or java.util.HashMap<Long,String> depending on which datatype is returned, when you retrive the empno.
Just blindly do a map.put(empno,null) for each duty element, and you will only have each employee in the hashmap once afterwards, as each additional addition of the same key will overwrite the existing.
After that, simply
for (String key : map.keySet()) {
// do your stuff
}
As I see it, you really don't need to sort anything to get there.
Related
I did a bit of investigating before posting this and found that the best way to find the data i need without having to iterate through a whole List is with a HashMap. Now I've never had to use HashMaps before and it's complicating me a lot.
Given this Client class
public class Client {
private String nroClient;
private String typeDoc;}
I gotta get a typeDoc given an unique nroClient
I've gotten this far
private String getTypeDoc(List<Client> clients, String nroClient) {
Map <String, Client> map = new HashMap<String, Client>();
for (Client client : clients)
{
map.put(client.getNroClient(), client);
}
}
It just doesn't seem right at all, and I have no idea how to advance. I'd really appreciate any input. Sorry if this has been asked before, i really tried to find a solution before posting. Thanks
You've basically got it, but building the map is obviously as slow (even slower, in fact) vs. just looping the list.
Given a j.u.List instance, you CANNOT answer the question 'get me the class in this list with ID x, and do it fast'.
The solution is to remove the list entirely and have that be a map.
If you ALSO need list-like aspects (For example, you need to be able to answer the question 'get me the 18th client'), you can either use LinkedHashMap which remembers the order in which you added things, but it still doesn't have something like a .get(18) method. If need be you can have a class to represent the notion of 'Clients', internally it has BOTH a list and a map, it has an add method that adds your client to both data structures, and now you can answer both 'get me the 18th client' and 'get me the client with this ID' quickly.
Are you trying to return the match?:
private String getTypeDoc(List<Client> clients, String nroClient)
{
String typeDocFound = null;
for (Client client : clients)
{
if(client.getNroClient().equals(nroClient)
{
typeDocFound = client.getTypeDoc();
break;
}
}
return typeDocFound;
}
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.
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 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
I'm attempting to execute an Upsert using the Novell JLDAP library, unfortunately, I'm having trouble finding an example of this. Currently, I have to:
public EObject put(EObject eObject){
Subject s = (Subject) eObject;
//Query and grab attributes from subject
LDAPAttributes attr = resultsToAttributes(getLDAPConnection().get(s));
//No modification needed - return
if(s.getAttributes().equals(attr)){
return eObject;
} else {
//Keys:
//REPLACE,ADD,DELETE, depending on which attributes are present in the maps, I choose the operation which will be used
Map<String,LDAPAttribute> operationalMap = figureOutWhichAttributesArePresent(c.getAttributes(),attr);
//Add the Modifcations to a modification array
ArrayList<LDAPModification> modList = new ArrayList<LDAPModification>();
for(Entry entry: operationalMap.getEntrySet()){
//Specify whether it is an update, delete, or insert here. (entry.getKey());
modList.add(new LDAPModification(entry.getKey(),entry.getValue());
}
//commit
connection.modify("directorypathhere",modList.toArray(new LDAPModification[modList.size()]));
}
I'd prefer to not have to query on the customer first, which results in cycling through the subject's attributes as well. Is anyone aware if JNDI or another library is able to execute an update/insert without running multiple statements against LDAP?
Petesh was correct - the abstraction was implemented within the Novell library (as well as the UnboundId library). I was able to "upsert" values using the Modify.REPLACE param for every attribute that came in, passing in null for empty values. This effectively created, updated, and deleted the attributes without having to parse them first.
In LDAP, via LDIF files, an upset would be a single event with two steps. A remove and add of a value. This is denoted by a single dash on a line, between the remove then the add.
I am not sure how you would do it in this library. I would would try to modList.remove and then modList.add one after another and see if that works.