How to update users list using DWR - java

I am developing chat client which can connect to Gtalk and Facebook.I am using DWR for the purpose.
Once I log into I have to populate the user s lists. On client side I have
function showUsersOnline() {
var cellFuncs = [ function(user) {
return '<i>'+user+'</i>';
} ];
LoginG.usersOnline( {
callback : function(users) {
dwr.util.removeAllRows('usersOnline');
dwr.util.addRows("usersOnline", users, cellFuncs, {
escapeHtml : false
});
On server side I am using Smack Api to get the roster list(online)
public void usersOnline() {
Roster roster = connection.getRoster();
Collection<RosterEntry> entries = roster.getEntries();
System.out.println(roster.getEntryCount());
int count1 = 0;
int count2 = 0;
for (RosterEntry r : entries) {
String user = r.getUser();
Presence presence = roster.getPresence(user);
if (presence.getType() == Presence.Type.available) {
System.out.println(user + " is online");
count1++;
} else {
System.out.println(user + " is offline");
count2++;
}
Now should I return the data as JSON or is there a way DWR can handle the collection???

If you modify your server method usersOnline() to return the Collection<RosterEntry> object then DWR will populate that in the argument of the callback function which in your case is function(users). So after the call is returned back to the callback function function(users) you can go through the users object to get the updates made to it by the server side method. The users object will need to be traversed like an array since you are returning a Collection or a List whatever applies.
Is this what you are looking for? More on this can be read here.

Related

CosmosDB : CosmosPatchOperation not working via Stored Procedure

I want to replace cosmos batch with Stored Proc as my requirement is to upsert 100+ records which cosmos batch does not support. I am adding 2 java objects and 1 CosmosPatchOperations
in List and passing to below method.Whenver I am adding cosmos patch object no rows got inserted/updated otherwise it is working fine.I want to perform both insertion and patch operation in same transaction. Can somebody please guide how to modify SP so that it supports both insert and patch operation.
String rowsUpserted = "";
try
{
rowsUpserted = container
.getScripts()
.getStoredProcedure("createEvent")
.execute(Arrays.asList(listObj), options)
.getResponseAsString();
}catch(Exception e){
e.printStackTrace();
}
Stored Proc
function createEvent(items) {
var collection = getContext().getCollection();
var collectionLink = collection.getSelfLink();
var count = 0;
if (!items) throw new Error("The array is undefined or null.");
var numItems = items.length;
if (numItems == 0) {
getContext().getResponse().setBody(0);
return;
}
tryCreate(items[count], callback);
function tryCreate(item, callback) {
var options = { disableAutomaticIdGeneration: false };
var isAccepted = collection.upsertDocument(collectionLink, item, options, callback);
if (!isAccepted) getContext().getResponse().setBody(count);
}
function callback(err, item, options) {
if (err) throw err;
count++;
if (count >= numItems) {
getContext().getResponse().setBody(count);
} else {
tryCreate(items[count], callback);
}
}
}
Patching doesn't appear to be supported by the Collection type in the Javascript stored proc API. I suspect this was done as it's more an optimisiation for remote calls and SP execute locally so it's not really neccessary.
API reference is here: http://azure.github.io/azure-cosmosdb-js-server/Collection.html
upsertDocument is expecting the full document.

Passing a String[] from react to springboot

I want to pass a String array of usernames from react to Spring so that I can then get some user details for each of those usernames and finally pass this back to react as a List<String>
So far in react, I am making an array of usernames, and then passing them as the request body to spring
const roundRobin = () => {
const userList = []
//Get list of entrants usernames to pass to backend
for(let i = 0; i < entrants.length; i++){
userList.push(entrants[i].username);
console.log(userList);
}
const List = JSON.stringify(userList)
//API call
apiCalls
.getRandomUserList(List)
.then((response) => {
console.log(response.data);
})
.catch((apiError) => {
if (apiError.response.data && apiError.response.data.validationErrors) {
setEditErrors(apiError.response.data.validationErrors);
}
console.log(apiError.response.data)
setPendingApiCall(false);
});
}
In spring my controller takes the request body as a String[]
//create a random list of members who have entered an event
#CrossOrigin
#GetMapping("/users/createRandomList")
List<String> randomList(#RequestBody String[] usernames) {
return userService.createRandomUserList(usernames);
}
The UserService then takes the String[] and changes it to a List and calls a method which randomly rearranges the order of the Strings, it then loops through the returned List (which are a username) and gets the User from the database and adds some details about that User to a new List This is then returned to react.
public List<String> createRandomUserList(String[] randomUsernames) {
List<String> users = new ArrayList<>();
List<String> randomUsersList = Arrays.asList(randomUsernames);
List<String> randomUsers = getRandomUsers(randomUsersList);
for (String randUsernames : randomUsers) {
User u = userRepository.findByUsername(randUsernames);
users.add(u.getFirstname() + " " + u.getSurname() + " " + u.getHandicap());
}
return users;
}
//Create list of entrants IDs in random order for tee times.
public List<String> getRandomUsers(List<String> userIds) {
int size = userIds.size();
List<String> passedList = userIds;
List<String> entrants = new ArrayList<>();
Random rand = new Random();
for(int i = 0; i < size; i++) {
int randomIndex = rand.nextInt(passedList.size());
entrants.add(passedList.get(randomIndex));
passedList.remove(randomIndex);
}
return entrants;
}
When I try and run this in my web app though, I get an HTTP 400 error,
{timestamp: 1640902047907, status: 400, message: 'Required request body is missing: java.util.List<j…ser.UserController.randomList(java.lang.String[])', url: '/api/1.0/users/createRandomList'}
I am not sure what I am doing wrong, as far as I can tell, I am passing an array to Spring, when I console.log(List), I get ["user1","user2"]
I think you should change the get mapping to post mapping and then use the List instead of String[], try in that way
#CrossOrigin
#GetMapping("/users/createRandomList")
List<String> randomList(#RequestBody List<String> usernames) {
return userService.createRandomUserList(usernames);
}
also change service methods according to the changes

Spring integration mail sets flag 'Flagged' after fetching email. Is there anyway to stop it from doing this?

I am trying to fetch emails based on SearchTerms like from, subject and body and I have implemented SearchTermStrategy interface which takes
java mail SearchTerm[] as constructor argument and I also have extended ImapMailReceiver class and override its searchForNewMessages(). here is the code
public class SearchTermStrategyImpl implements SearchTermStrategy {
private final SearchTerm[] searchTerms;
public SearchTermStrategyImpl(SearchTerm[] searchTerms) {
this.searchTerms = searchTerms;
}
#Override
public SearchTerm generateSearchTerm(Flags supportedFlags, Folder folder) {
SearchTerm searchTerm = null;
for (int i = 0; i < searchTerms.length; i++) {
if (i == 0) {
searchTerm = searchTerms[i];
} else {
searchTerm = new AndTerm(searchTerm, searchTerms[i]);
}
}
return searchTerm;
}
}
overridden method of ImapMailReceiver
#Override
protected Message[] searchForNewMessages() throws MessagingException {
Message[] messages = null;
Folder folder = getFolder();
super.setSearchTermStrategy(searchTermStrategy);
SearchTerm searchTerm = searchTermStrategy.generateSearchTerm(null, null);
if (folder.isOpen()) {
messages = searchTerm==null ? folder.getMessages() : folder.search(searchTerm);
} else {
throw new ImapException("Folder is closed");
}
return messages.length > 0 ? messages : new Message[0];
}
I have also set SimpleContent, ShouldMarkMessagesAsRead and AutoCloseFolder values as false of ImapMailReceiver.
At the end, i got message in payload which has additional flag 'Flagged', which is not right. Is there anyway to keep emails Flags as it is?
I have tried setting Flag.Flagged to false on each messages but it would be wrong in two ways
if user has flagged some of emails that are important.
By iterating over all emails and setting Flagged as false which will be a big performance hit and wrong as above.
I think, extra processing after fetching emails can be reduced in a situation where SelectorExpression is not specified (avoid call to searchAndFilterMessages() method )
Flags.Flag.FLAGGED is set (in AbstractMailReceiver.setMessageFlags()) if the server doesn't support both Flags.Flag.RECENT and Flags.Flag.USER.
(These flags are used in the default search term).
It looks like you should be able to override setAdditionalFlags() and use message.getFlags().removeFlag(Flags.Flag.FLAGGED) (after calling super.SetAdditionalFlags() which sets Flags.Flag.SEEN).

How to publish multiple event using EventQueues.publish in zk

Hope your problem is resolved, but my problem is still there
and I thought that you can help me to get out of this problem.
actually I had multiple events to publish one by one as per user
selection for eg: user select Season, Service, DateFrom and
DateTo and then clicks on the refresh button.
When the refresh button is clicked I had used the above logic to
get all the datas using the below mentioned code
public void onClick$ref(Event event){
if(lbox_service.getSelectedIndex() != 0 || lbox_season.getSelectedIndex() != 0)
{
if(lbox_service.getSelectedIndex() == 0)
{
setService_id("0");
}
else
{
setService_id(lbox_service.getSelectedItem().getValue().toString());
}
if(lbox_season.getSelectedIndex() == 0)
{
setSeason_id("0");
}
else
{
setSeason_id(lbox_season.getSelectedItem().getValue().toString());
}
System.out.println("Service Index 11 : "+ lbox_service.getSelectedIndex());
System.out.println("Season Index 11 : "+ lbox_season.getSelectedIndex());
EventQueue evtQ = EventQueues.lookup("myEventQueue", EventQueues.APPLICATION, true);
//evtQ.publish(new Event("service_id", self, lbox_service.getSelectedItem().getValue().toString()));
//evtQ.publish(new Event("season_id", self, lbox_season.getSelectedItem().getValue().toString()));
evtQ.publish(new Event("service_id", self, getService_id()));
evtQ.publish(new Event("season_id", self, getSeason_id()));
//evtQ.publish(new Event("onClickRef", null, lbox_service.getSelectedItem().getValue().toString()));
//evtQ.publish(new Event("onClickRef", null, lbox_season.getSelectedItem().getValue().toString()));
/*.publish(new Event("onClickRef", null, lbox_service.getSelectedItem().getValue().toString()));
EventQueues.lookup("myEventQu", EventQueues.DESKTOP, true).publish(new Event(
"onClickRef", null, lbox_season.getSelectedItem().getValue().toString()));*/
}
else
{
setService_id("0");
setSeason_id("0");
EventQueue evtQ = EventQueues.lookup("myEventQueue", EventQueues.APPLICATION, true);
evtQ.publish(new Event("service_id", self, getService_id()));
evtQ.publish(new Event("season_id", self, getSeason_id()));
System.out.println("Service Index : "+ lbox_service.getSelectedIndex());
System.out.println("Season Index : "+ lbox_season.getSelectedIndex());
}
}
now i had publish all my value and after that my new Controller
run that will subscribe those published values. using the
below code
public void doAfterCompose(Component comp) throws Exception {
super.doAfterCompose(comp);
EventQueues.lookup("myEventQueue", EventQueues.APPLICATION, true).subscribe(new EventListener() {
public void onEvent(Event event) throws Exception {
/*String service = (String) event.getData();
logger.info("Servive $$$$$$$$$ " + service);
//String season = (String) event.getData();
//logger.info("Season $$$$$$$$$ " + season); */
if("service_id".equals(event.getName())) {
setService_id((String) event.getData());
baseController.setFilter_bar(true);
System.out.println("Service Id :" +event.getData());
}
else if("season_id".equals(event.getName())) {
setSeason_id((String) event.getData());
baseController.setFilter_bar(true);
System.out.println("Season Id :" +event.getData());
}
/*setService_id((String) event.getData());
setSeason_id((String) event.getData());*/
/*if("season_id".equals(event.getName())){
setSeason_id((String) event.getData());
}else
{
setSeason_id("0");
}*/
System.out.println("Filter bar :" +baseController.isFilter_bar());
if(baseController.isFilter_bar() == true)
{
String dateFrom = "";
String dateTo = "";
String order = "2";
List TDRetailers = verificationStoreHibernateDao.getTraditionalRetailers(
getService_id(), getSeason_id(), dateFrom, dateTo, order);
//VerificationStoreHibernateDao storeHibernateDao = new VerificationStoreHibernateDao();
//List TDRetailers = this.verificationStoreHibernateDao.getTraditionalRetailers(service_id);
//ListModel listModel = this.retailers.getModel();
ListModelList listModelList = (ListModelList) retailer.getModel();
listModelList.clear();
listModelList.addAll(TDRetailers);
baseController.setFilter_bar(true);
}
}
});
}
but actully my problem is with running the query and with
getting those published values. Based on them I will be able to
run my Traditional getTraditionalRetailers queries.
My problem is
how to publish multiple events values. Is it the right way
that I had done.
as I had done separate publish, everytime
I publish new value The query runs, the result is that i had
mutiple time query execution. for example If i will publish two
values the queries run's for the two times and if I publish
three values the query executes for three time.
I don't know what is their problem. Help me to solve my error.
The event object passed through EventQueue is where you put your payload there. You can just define an aggregate Event class and collect information and publish them in a whole.
If you can publish all information in a whole(using an aggregate Event), this is solved automatically.

Google Spreadsheet API - find the first empty cell in a column?

Is there a good way to get the first empty cell in a column from Google's spreadsheet service via Java?
I know I can use:
public CellFeed CheckColumn(int row, int col)
throws IOException, ServiceException {
CellQuery query = new CellQuery(cellFeedUrl);
query.setMinimumRow(row);
query.setMaximumRow(row);
query.setMinimumCol(col);
query.setMaximumCol(col);
query.setReturnEmpty(true);
CellFeed feed = service.query(query, CellFeed.class);
int cell_loc[];
for (CellEntry entry : feed.getEntries()) {
cell_loc=CheckIfEmpty(entry);
}
return cell_loc;
}
And walk through the entries, but I'd rather not load the entire column at once, it's slow for my users and it seems bad to just walkthrough the entire column
Any thoughts?
This small snippet will create a function in Google Spreadsheet with Google Apps Script:
function emptySpace(array) {
// set counter
var counter = 0;
// itterate through values
for (i in array){
if (array[i].length > 1) {
throw ("Only single column of data");
} else {
if(array[i][0] != "") {
counter++;
} else {
break;
}
}
}
// return value + 1
return counter + 1;
}
Add this script, via the script editor, to your spreadsheet and the function emptySpace is available throughout the worksheet, like so: =emptySpace(A1:A7).
See example file I've created: empty space

Categories

Resources