createChannel method returns null when implementing group chat using applozic sdk, android.
List<String> channelMembersList = new ArrayList<String>();
channelMembersList.add(p.getMobile());
channelMembersList.add("9567600846");
channelMembersList.add("8089117582");
final ChannelInfo channelInfo = new ChannelInfo("GroupName",channelMembersList);
channelInfo.setType(Channel.GroupType.PRIVATE.getValue().intValue());
runOnUiThread(new Runnable() {
#Override
public void run() {
channel = ChannelService.getInstance(WelcomeActivity.this).createChannel(channelInfo);
}
});
here, channel object is always null although the ChannelInfo object is created.Someone please do help...
We added an async task you can use this async task for creating a group/channel pass the details like group members, group name and some details are optional.
UPDATE:
AlChannelCreateAsyncTask.TaskListenerInterface channelCreateTaskListener = new AlChannelCreateAsyncTask.TaskListenerInterface() {
#Override
public void onSuccess(Channel channel, Context context) {
Log.i("Group","Group response :"+channel);
}
#Override
public void onFailure(ChannelFeedApiResponse channelFeedApiResponse, Context context) {
}
};
List<String> groupMembersUserIdList = new ArrayList<>();
groupMembersUserIdList.add("user1");
groupMembersUserIdList.add("user2");
groupMembersUserIdList.add("user3");//Note:while creating group exclude logged in userId from list
ChannelInfo channelInfo = new ChannelInfo("Group name",groupMembersUserIdList);
channelInfo.setType(Channel.GroupType.PUBLIC.getValue().intValue()); //group type
channelInfo.setImageUrl(""); //pass group image link URL
//channelInfo.setChannelMetadata(channelMetadata); //Optional option for setting group meta data
//channelInfo.setClientGroupId(clientGroupId); //Optional if you have your own groupId then you can pass here
AlChannelCreateAsyncTask channelCreateAsyncTask = new AlChannelCreateAsyncTask(context,channelInfo,channelCreateTaskListener);
channelCreateAsyncTask.execute();
Creating Group with applozic
Create a group with a specific group type
Channel.GroupType.PRIVATE.getValue().intValue()
Public group with type : Channel.GroupType.PUBLIC.getValue().intValue()
Open group with type : Channel.GroupType.OPEN.getValue().intValue()
Note: Group meta data is optional
Setting group meta data for messages like created group, left group, removed from group, group deleted, group icon changed and group name changed.
Note: If the channel meta data is set as empty String, no notification is sent to other users in the group/channel.
ChannelMetadata channelMetadata = new ChannelMetadata();
channelMetadata.setCreateGroupMessage(ChannelMetadata.ADMIN_NAME + " created " + ChannelMetadata.GROUP_NAME);
channelMetadata.setAddMemberMessage(ChannelMetadata.ADMIN_NAME + " added " + ChannelMetadata.USER_NAME);
channelMetadata.setRemoveMemberMessage(ChannelMetadata.ADMIN_NAME + " removed " + ChannelMetadata.USER_NAME);
channelMetadata.setGroupNameChangeMessage(ChannelMetadata.USER_NAME + " changed group name " + ChannelMetadata.GROUP_NAME);
channelMetadata.setJoinMemberMessage(ChannelMetadata.USER_NAME + " joined");
channelMetadata.setGroupLeftMessage(ChannelMetadata.USER_NAME + " left group " + ChannelMetadata.GROUP_NAME);
channelMetadata.setGroupIconChangeMessage(ChannelMetadata.USER_NAME + " changed icon");
channelMetadata.setDeletedGroupMessage(ChannelMetadata.ADMIN_NAME + " deleted group " + ChannelMetadata.GROUP_NAME);
Following place holders will be replaced
ChannelMetadata.ADMIN_NAME : admin name of the group
ChannelMetadata.USER_NAME : user name of the user
ChannelMetadata.GROUP_NAME : group name
Please check the docs for this https://www.applozic.com/docs/android-chat-sdk.html
In 5.34 version
ChannelService.getInstance(WelcomeActivity.this).createChannel(channelInfo) assign variable of AlResponse.
and AlResponse is null after ChannelService.getInstance(WelcomeActivity.this).createChannel(channelInfo)
Related
I need to show elements on a table depending on the element (Person) clicked on another table. The problem is that, using a Service, if the user clicks on two elements of the first table very quickly, the data of the two elements is showed in the table, and I only want to show the data from the last one clicked. Hope you can help me.
Here is my code:
personTable.getSelectionModel().selectedItemProperty().addListener(
(observable, oldValue, newValue) -> {
try {
contactoTable.setPlaceholder(new Label("Cargando..."));
showPersonDetails(newValue);
} catch (SQLException ex) {
Logger.getLogger(PersonOverviewController.class.getName()).log(Level.SEVERE, null, ex);
}
});
And showPersonDatails:
contactoTable.setVisible(true);
contactoTable.getItems().clear();
firstNameLabel.setText(person.getFirstName());
lastNameLabel.setText(person.getLastName());
mailLabel.setText(person.getMail());
phoneLabel.setText(person.getPhone());
descriptionLabel.setText(person.getDescription());
service = new Service<Void>() {
#Override
protected Task<Void> createTask() {
return new Task<Void>() {
#Override
protected Void call() throws Exception {
//Background work
DBManager db = new DBManager();
String query = "SELECT * FROM eventos";
ResultSet r = db.executeSelect(query);
contactoTable.getItems().clear();
contactoData.clear();
while (r.next()) {
String q = "SELECT * FROM " + r.getString("Nombre").replace(" ", "_") + " WHERE Nombre = '" + person.getFirstName() + "' AND Apellidos = '" + person.getLastName() + "' AND Correo = '" + person.getMail() + "'";
ResultSet result = db.executeSelect(q);
while (result.next()) {
contactoData.add(new Row(r.getString("Nombre"), result.getString("Asistencia")));
}
}
final CountDownLatch latch = new CountDownLatch(1);
Platform.runLater(() -> {
try {
//FX Stuff done here
contactoTable.setPlaceholder(new Label("No invitado a ningĂșn evento"));
contactoTable.setItems(contactoData);
} finally {
latch.countDown();
}
});
latch.await();
//Keep with the background work
return null;
}
};
}
};
service.start();
You are referencing the same data list (contactoData) from multiple threads, with apparently no synchronization on the list. If the user selects two different items in rapid succession, you launch a service for each one, each service running its task in a different thread. Consequently you have no control over the order the two different threads perform their (multiple) manipulations on contactoData. For example, it is possible (even probable) that the order for two services executing asynchronously is:
First service clears the list
Second service clears the list
First service adds elements to the list
Second service adds elements to the list
and in this case the list contains elements generated by both services, not just one of them.
So you should have your tasks operate on, and return, a new list they create. Then process that list on the FX Application Thread.
It's also not clear why you need a service here, as you only seem to ever use each service once. You may as well just use a task directly.
You also probably want to ensure that the last selection is the one displayed. Since the tasks are running asynchronously, it's possible that if two tasks were started in quick succession, the second would complete before the first. This would result in the second selection being displayed, and then the first selection replacing it. You can avoid this by doing the UI update in an onSucceeded handler, and canceling any current task when you start a new one (thus preventing the currently-executing task from invoking its onSucceeded handler).
Finally, it's really not clear to me why you are making the task wait until the UI is updated.
Here is an updated version of your code:
private Task<List<Row>> updateContactTableTask ;
// ...
private void showPersonDetails(Person person) {
contactoTable.getItems().clear();
firstNameLabel.setText(person.getFirstName());
lastNameLabel.setText(person.getLastName());
mailLabel.setText(person.getMail());
phoneLabel.setText(person.getPhone());
descriptionLabel.setText(person.getDescription());
if (updateContactTableTask != null && updateContactTableTask.isRunning()) {
updateContactTableTask.cancel();
}
updateContactTableTask = new Task<List<Row>>() {
#Override
protected List<Row> call() throws Exception {
List<Row> resultList = new ArrayList<>() ;
//Background work
DBManager db = new DBManager();
String query = "SELECT * FROM eventos";
ResultSet r = db.executeSelect(query);
// quit if we got canceled here...
if (isCancelled()) {
return resultList;
}
while (r.next() && ! isCancelled()) {
// Note: building a query like this is inherently unsafe
// You should use a PreparedStatement in your DBManager class instead
String q = "SELECT * FROM " + r.getString("Nombre").replace(" ", "_") + " WHERE Nombre = '" + person.getFirstName() + "' AND Apellidos = '" + person.getLastName() + "' AND Correo = '" + person.getMail() + "'";
ResultSet result = db.executeSelect(q);
while (result.next()) {
resultList.add(new Row(r.getString("Nombre"), result.getString("Asistencia")));
}
}
return resultList ;
}
};
updateContactTableTask.setOnSucceeded(e -> {
// not really clear you still need contactoData, but if you do:
contactoData.setAll(updateContactTableTask.getValue());
contactoTable.setPlaceholder(new Label("No invitado a ningĂșn evento"));
contactoTable.setItems(contactoData);
});
updateContactTableTask.setOnFailed(e -> {
// handle database errors here...
});
new Thread(updateContactTableTask).start();
}
As an aside, it's not clear to me if, and if so, how, you are closing your database resources. E.g. the result sets never seem to get closed. This could cause resource leaks. However this is incidental to the question (and relies on knowing how your DBManager class is implemented), so I won't address it here.
I have a list of group names which the app is reading from external .txt.
I want to pass to method as a List <String> group names and to execute dql query something like:
for (String s : groupnames) {
dql = "DROP GROUP " + s;
System.out.println("dropped group: " + s;
}
How to write/execute DQL?
I have done it by myself:
private static void deleteGroups(List<String> groupsToDelete) {
try {
DfClientX clientX = new DfClientX();
IDfQuery query = clientX.getQuery();
for (String s : groupsToDelete){
query.setDQL("DROP GROUP '" + s + "'");
printInfo("Executing DQL: " + query.getDQL());
query.execute(_session, 0);
}
} catch (DfException e) {
printError(e.getMessage());
DfLogger.error("app", "DQL DROP GROUP execution", null,e);
}
}
Not quite sure does CS permit to delete group via DFC but it should be like:
IDfQuery query = new DfQuery();
query.setDQL("DROP GROUP <group_name>");
query.execute(getSession(), IDfQuery.DF_EXEC_QUERY);
There is for sure way to instantiate group object in memory and call .delete() method. I'll try to check it out.
I'm developing a demo and I'm stuck with this.
I want to list in a java web app all the attachments (PDFs for example), but a I am not able to retrieve and list them.
I'm only able to retrieve common data (String, Ints).
Is there a standard way to retrieve and show ?
I been reading all the posts but nothing seems to work.
Here is where I add the vendor, with the attachment:
public void addVendor(final Vendor vendor, final InputStream inputStream, final long size, final String contentType)
{
final Database db = getDb();
final int id = Integer.valueOf(vendor.get_id()) + 1;
final Response r1 = db.saveAttachment(inputStream, vendor.getName() + ".txt", contentType, String.valueOf(id), null);
vendor.setAttachment(r1);
final Response r = db.post(vendor);
System.out.println("Vendor created successfully. Id: " + r.getId() + ", rev: " + r.getRev());
System.out.println("File created successfully. Id: " + r1.getId() + ", rev: " + r1.getRev());
}
Here I where I try to retrive the data:
public List<Vendor> getAllVendors()
{
List<Vendor> Vendors = new ArrayList<Vendor>();
final List<Vendor> vend2 = new ArrayList<Vendor>();
//Get db
final Database db = getDb();
final InputStream s = null;
//Get all documents
Vendors = db.view("_all_docs").includeDocs(true).query(Vendor.class);
final Database db1 = getDb();
for (final Vendor vend : Vendors) {
final Response r1 = vend.getAttachment();
final int id = Integer.valueOf(vend.get_id()) + 1;
// Here I am look to the attachment with the _ID and _REV
final InputStream in = db1.find(r1.getId(), r1.getRev()); vend.setInput(in); vend2.add(vend);
}
return Vendors;
}
I this last code, I intended to create a new list with all my Vendor data plus the blob.
When I add the vendor ( in the first part ) , I saved the " response " of the attachement in the vendor object, SO when I tried to retrive I have the data to work with ( _id and _rev ) .
I'm assuming you want to list all documents that contain attachments. If so, you can create a MapReduce view similar to this:
function(doc) {
if (doc._attachments) {
emit(doc._id, null);
}
}
You would then call the view using something like this to get a list of document ids of documents that contain attachments:
GET /dbname/_design/designdocname/_view/docswithattachments
The above GET request would look something like this in Java:
List<Foo> list = db.view("designdocname/docswithattachments")
.query(Foo.class);
I'm following this tutorial to write a workflow for 3 HTML forms (without using CQ5 form component and CQ5 workflow submit button). I use this code to write Process step handling for my workflow:
public class MyProcess implements WorkflowProcess {
public void execute(WorkItem item, WorkflowSession session,
MetaDataMap map) throws WorkflowException {
boolean advanced = false;
Boolean goBack = map.get("goBack", Boolean.class);
List<Route> routes = null;
if (goBack == null || goBack == false) {
routes = session.getRoutes(item);
} else {
routes = session.getBackRoutes(item);
}
for (Route route : routes) {
LOG.info("===============================");
LOG.info("Rout name: " + route.getName());
LOG.info("Destinations: ");
for (WorkflowTransition dest: route.getDestinations()) {
LOG.info("dest: " + dest.getTo().getTitle());
}
LOG.info("===============================");
if (route.hasDefault()) {
String fromTitle = item.getNode().getTitle();
String toTitle = route.getDestinations().get(0).getTo()
.getTitle();
session.complete(item, route);
LOG.info("===============================");
LOG.info(item.getId() + " advanced from " + fromTitle
+ " to " + toTitle);
LOG.info("===============================");
advanced = true;
}
}
// fallback if no route was marked as default
if (!advanced) {
session.complete(item, routes.get(0));
String fromTitle = item.getNode().getTitle();
String toTitle = routes.get(0).getDestinations().get(0).getTo()
.getTitle();
LOG.info("===============================");
LOG.info(item.getId() + " advanced from " + fromTitle + " to "
+ toTitle);
LOG.info("===============================");
}
}
}
My question is: after i use session.complete to advance to next step, how can i refresh the workflow session to reach the current step information.
I think #yashahuja is correct. I was poking around and on the aem 'working with workflow' page I found some information about persisting data throw workflow steps using MetaDataMap.
From this page: http://dev.day.com/docs/en/cq/current/workflows/wf-extending.html
"Use workflow metadata to persist information that is required during the lifetime of the workflow. A common requirement of workflow steps is to persist data for future use in the workflow, or to retrieve the persisted data.
Workflow metadata is stored in a MetaDataMap object. The Java API provides the Workflow.getMetaDataMap method that returns the MetaDataMap object. Also, the WorkItem.getWorkflowData method returns a WorkflowData object that provides the same getMetaDataMap object.
Therefore, the workflow MetaDataMap object is available to the OSGi service or ECMA script of a step component."
example:
public void execute(WorkItem item, WorkflowSession session, MetaDataMap args) throws WorkflowException {
MetaDataMap wfd = item.getWorkflow().getMetaDataMap();
wfd.put("mykey", "My Step Value");
Set<String> keyset = wfd.keySet();
Iterator<String> i = keyset.iterator();
while (i.hasNext()){
Object key = i.next();
log.info("The workflow medata includes key {} and value {}",key.toString(),wfd.get(key).toString());
}
I have the following functions to mark attendance of an employee:
public void updateDailyAttendance(ActionRequest areq, ActionResponse aRes) throws Exception {
int totalEmployees = EmployeeLocalServiceUtil.getEmployeesCount();
List<Employee> employeeAttendanceDetails = MISPortalActionUtil.getEmployeeData();
String datt = areq.getParameter("datt");
String Imatt = areq.getParameter("matt");
String yatt = areq.getParameter("yatt");
int Lmatt = Integer.parseInt(Imatt);
String matt = Integer.toString(Lmatt +1);
String dateOfAttendance = datt +"/"+ matt +"/"+ yatt;
SimpleDateFormat dateOfAttendanceFormat = new SimpleDateFormat("dd/MM/yyyy");
java.util.Date date_Of_Attendance = dateOfAttendanceFormat.parse(dateOfAttendance);
System.out.println("Today's attendance date is: " + date_Of_Attendance);
ArrayList<String> attNames = new ArrayList<String>();
for (Employee emp: employeeAttendanceDetails) {
long empId = emp.getEmpId();
String name = "updateattendance" + " " +Long.toString(emp.getEmpId());
System.out.println("updateattendance name : " + name);
String value = getAttendanceValue(areq,name);
System.out.println("updateattendance value : " + value);
long attPKey = CounterLocalServiceUtil.increment(Employee.class.getName());
Attendance newAttendanceInstance = new AttendanceImpl();
String checkAttMarkStatus = newAttendanceInstance.getAttStatus();
System.out.println("checkAttMarkStatus: " + checkAttMarkStatus);
//loop to mark the attendance if it has not been pre marked
if(checkAttMarkStatus != "Absent" || checkAttMarkStatus != "Half Day" ) {
newAttendanceInstance.setAttId(attPKey);
newAttendanceInstance.setAttDate(date_Of_Attendance);
newAttendanceInstance.setAttStatus(value);
newAttendanceInstance.setAttANStatus(value);
newAttendanceInstance.setAttFNStatus(value);
newAttendanceInstance.setEmpId(empId);
AttendanceLocalServiceUtil.addAttendance(newAttendanceInstance);
}//loop to mark the attendance if it has not been pre marked
}
}
/**
* The getAttendanceValue() is used to fetch parameter values and pass the values to updateDailyAttendance function
* #param areq
* #return
* #throws SystemException
*/
private String getAttendanceValue(ActionRequest areq, String paramName) {
Enumeration parameters = areq.getParameterNames();
System.out.println("updateattendance paramName : " + paramName);
while (parameters.hasMoreElements()) {
System.out.println("updateattendance paramName inside while : " + paramName);
String parameterName = parameters.nextElement().toString();
System.out.println("updateattendance paramName new : " + paramName);
System.out.println("the paramName " + paramName + " parameterName " + parameterName);
if (paramName.equals(parameterName)) {
return areq.getParameter(parameterName);
}
}
throw new IllegalStateException("Parameter updateattendance is not found");
}
In my jsp the list of employees is populated and user is allowed to mark attendance through radio button. This approach works well when I am marking attendance for all the employees.
But problem comes when I have pre marked attendance status.
Whenever a user applies for leave his attendance status is premarked and the attendance form for marking attendance for this employee is shown as marked and disabled.. So when I try to mark attendance when pre marked attendance exists, it doesnt mark attendance for other employees. ex. Suppose if the 4th entry is pre marked as absent, and I mark attendance for other employees, then only first three entries are added in the database and then it doesnt find the fourth entry and throws the illegal exception:
Parameter updateattendance is not found
How should I change my getAttendanceValue() function to suit my purpose?
EDIT:
The JSP part where I am fetching the values:
<label>Present</label><input type = "radio" name ='updateattendance <%=((Object[])search)[5]%>' value = "Present" />
<label>Absent</label><input type = "radio" name= 'updateattendance <%=((Object[])search)[5]%>' value = "Absent" />
IN the above code I have kept a check to see if it is pre marked. I have put the above code fragment in if-else block for pre marked attendance check
You're doing this:
Attendance newAttendanceInstance = new AttendanceImpl();
String checkAttMarkStatus = newAttendanceInstance.getAttStatus(); // most likely null or ""
System.out.println("checkAttMarkStatus: " + checkAttMarkStatus);
So I don't expect the correct status to be held by the object that you just created without any reference to previous state. My expectation is that checkAddMarkStatus is now "" (empty string) or null
Further you check for identity of strings, not equality (this is a huge difference in java:
if(checkAttMarkStatus != "Absent" || checkAttMarkStatus != "Half Day" ) {
You should rather use String.equal (and be aware of null values), but due to the issue described above, this will not help you without sorting out both issues. There might be more, but this is what I found on first sight.
Following the comments and your question update, I'm still missing to see the actual intent in the code. However, I'd advise to not use an exception like you do for a case that doesn't seem exceptional - rather use proper return values and check for these values - e.g. if someone never attended, have a value to signal this and react accordingly. If you throw an exception and don't catch it, you must expect things like you mention (e.g. half-executed methods)