Hello,
I’‘ve written a little java class to go to our database open the users table and generate accounts on openim from those accounts. This all works really well but I’'ve run into a little problem… so let me lay it down for ya…
First I hit the database and build an array of users objects to be create.
I then loop this array and create the account if it doesn’'t exist.
After all the accounts have been created I login as each user and loop the user array again adding those users to that currently logged in user. Each of the user objects in the array have a department property that I’'m setting as the group.
First user gets all the users in the correct groups on the roster list.
Second user it’'s really good but since the first user already added this user to their list the first user shows up in the second users “General” group.
By the time I hit the last user object in the array everyone is added to the “General” group. Thus the problem comes into play…
I wrote another function to correct the group problem but it doesn’'t commit the change for some reason here is the code for the group fix:
public static void checkGroups(CrimsHRData crimsData){
try {
//for each user
CrimsHRData.User theUser;
CrimsHRData.User theCurrentRosterPerson;
RosterEntry tmpObj; if (!crimsData.users.isEmpty()) {
for (int i = 0; i <= crimsData.users.size() - 1; i++) {
conn2 = new XMPPConnection(OPENIMSERVER, OPENIMSERVERPORT); theUser = (CrimsHRData.User) crimsData.users.get(i);
System.out.println("--- Roster Check For "+theUser.networkLogin+" ---");
//next login as each of the above users after all accounts have been created
conn2.login(theUser.networkLogin, OPENIMGLOBALUSERPASSWORD);
conn2.getRoster().setSubscriptionMode(Roster.SUBSCRIPTION_MANUAL);
Roster roster = conn2.getRoster(); //check that the people in the list are in the correct groups
for (Iterator j = roster.getEntries(); j.hasNext(); ) {
tmpObj = ( (RosterEntry) j.next());
ArrayList usersGroups = new ArrayList();
//System.out.println(tmpObj.toString()); for (Iterator jj = tmpObj.getGroups(); jj.hasNext(); ) {
String tmpStr = ( (RosterGroup) jj.next()).getName();
usersGroups.add(tmpStr);
//System.out.println(tmpObj.getUser() + " is a member of " + tmpStr);
} //find the current roster user in the master array list and get it''s group
for (int cp = 0; cp <= crimsData.users.size() - 1; cp++) {
theCurrentRosterPerson = (CrimsHRData.User) crimsData.users.get(cp);
if (!theCurrentRosterPerson.networkLogin.equalsIgnoreCase(theUser.networkLogin)) {
String tmpStr = tmpObj.getUser().substring(0, tmpObj.getUser().indexOf("@"));
if (theCurrentRosterPerson.networkLogin.equalsIgnoreCase(tmpStr)) {
//they are equal lets do the rest of the code then break
if (!usersGroups.get(0).toString().equalsIgnoreCase(theCurrentRosterPerson.department)) { RosterGroup currGroup = conn2.getRoster().getGroup(usersGroups.get(0).toString());
RosterGroup newGroup = conn2.getRoster().getGroup(theCurrentRosterPerson.department.toString());
if (newGroup == null){
//the group doesn''t exist create it
newGroup = conn2.getRoster().createGroup(theCurrentRosterPerson.department.toString());
System.out.println(" Added Group: "+theCurrentRosterPerson.department.toString());
}
RosterEntry entryToMove = currGroup.getEntry(tmpObj.getUser()); newGroup.addEntry(entryToMove);
currGroup.removeEntry(entryToMove); //is it not yet commited? why isn''t it saving the change here System.out.println(" -> Moved " + tmpObj.getUser() + " from " + usersGroups.get(0).toString() + " to " + theCurrentRosterPerson.department);
} break;
}
else {
//they are not equal try the next one
}
} //end if
} usersGroups = null;
}
conn2.close();
}
}
}
catch (XMPPException ex) {
ex.printStackTrace();
}
}
It doesn’'t commit the change in groups… why not? what am I missing?
Thanks!
Michael,
First I hit the database and build an array of users objects to be create.
I then loop this array and create the account if it doesn’'t exist.
Ok.
After all the accounts have been created I login as each user and loop the user array again adding those users to that currently logged in user. Each of the user objects in the array have a department property that I’'m setting as the group.
First user gets all the users in the correct groups on the roster list.
Second user it’'s really good but since the first user already added this user to their list the first user shows up in the second users “General” group.
Hmmm, this is strange. Let’‘s say that we have userA and userB. When we add userB to userA’‘s roster in group1 then we end up with group1 in userA that contains a userB. On the other hand we end up with userA as an unfiled entry in userB’‘s roster (if we are using the method SUBSCRIPTION_ACCEPT_ALL in userB’'s roster).
If we then add userA to userB’‘s roster in group2 we should still have the roster of userA unmodified while userB’'s roster should now have a group called group2 containing userA.
This means that, in your case, you shouldn’‘t have users in a group called “General”. All the roster entries (users) should be in their corresponding group (department). If we could take a look at your code we could try to figure out what’'s going on. It would be helpful if you also post the transmitted XML packets (you can use the debugger to get this info).
Regarding the “uncommited changes” it would also be helpful if you post the sent packets (XML). BTW, you shouldn’'t be setting the subscription mode to SUBSCRIPTION_MANUAL unless you register a listener for handling presence packets.
Regards,
– Gato
Right… but that appears to be exactly my problem… sorry code doesn’'t paste in here very nice. Here is the function that I am using to create the users and groups for each user…
public static void createUsersAndGroups(CrimsHRData crimsData){ try { //ok now that all the accounts have been created login as each of those accounts and edit the roster and groups
CrimsHRData.User theUser; if (!crimsData.users.isEmpty()){
for (int i = 0; i <= crimsData.users.size()-1; i++) {
conn2 = new XMPPConnection(OPENIMSERVER, OPENIMSERVERPORT); theUser = (CrimsHRData.User) crimsData.users.get(i); //next login as each of the above users after all accounts have been created
conn2.login(theUser.networkLogin,OPENIMGLOBALUSERPASSWORD);
conn2.getRoster().setSubscriptionMode(Roster.SUBSCRIPTION_MANUAL);
System.out.println("--- Logged In As: "+theUser.networkLogin+" ---");
Roster roster = conn2.getRoster(); //list the currently logged in users roster info groups and reg''d users
ArrayList usersGroups = new ArrayList(); for (Iterator j=roster.getGroups(); j.hasNext(); ) {
String tmpStr = ((RosterGroup)j.next()).getName();
usersGroups.add(tmpStr);
System.out.println(" Existing Group: "+tmpStr);
} //create the groups that do not yet exist
if (!crimsData.groups.isEmpty()){ for (int k=0; k <= crimsData.groups.size()-1; k++) {
boolean b = false;
String theGroup = crimsData.groups.get(k).toString(); for (int kk=0; kk <= usersGroups.size()-1; kk++){
String theUserGroup = usersGroups.get(kk).toString();
if (!theGroup.equalsIgnoreCase(theUserGroup)) {
//!=
b = false;
} else {
//in list
b = true;
break;
}
}
if (b == false) {
//the group doesn''t exist so lets create it
System.out.println(" Added Group: "+theGroup);
conn2.getRoster().createGroup(theGroup);
}
} } else {
System.out.println("No groups to create.");
} //if the user doesn''t exist in the current roster then create the user ArrayList usersJIDs = new ArrayList(); for (Iterator j = roster.getEntries(); j.hasNext(); ) {
RosterEntry tmpObj = ((RosterEntry)j.next());
usersJIDs.add(tmpObj);
System.out.println(" Exiting Entry: "+tmpObj.toString());
} //add users to the roster in the perspective groups
for (int u = 0; u <= crimsData.users.size()-1; u++) {
//get the current user item here theRosterAddition
CrimsHRData.User theRosterAddition = (CrimsHRData.User) crimsData.users.get(u); boolean b = false; for (int kk = 0; kk <= usersJIDs.size()-1; kk++) {
RosterEntry tmpObj = ((RosterEntry)usersJIDs.get(kk));
theUserJIDs = tmpObj.getUser().substring(0,tmpObj.getUser().indexOf("@")); //now compare the user and group part of the new user to make sure the user is in the right group
if (!theRosterAddition.networkLogin.equalsIgnoreCase(theUserJIDs)) {
//!=
b = false;
}
else {
//in list
b = true;
break;
}
} if (b) {
//user exists check the group of the user and move to the correct group
if (!theRosterAddition.networkLogin.equalsIgnoreCase(theUser.networkLogin)) {
//do nothing at this time we''ll do the group check in the next function
} }
else {
//the user doesn''t exist so lets create it
if (!theRosterAddition.networkLogin.equalsIgnoreCase(theUser.networkLogin)) {
String[] groups = {theRosterAddition.department};
roster.createEntry(theRosterAddition.networkLogin + "@" + OPENIMSERVER, theRosterAddition.employeeName,groups);
System.out.println("Added Roster: " + theRosterAddition.networkLogin + "@" + OPENIMSERVER);
} } } //close connection
conn2.close(); } } System.out.println("--- Accounts Create Done! ---");
}
catch (XMPPException ex) {
ex.printStackTrace();
}
}
Here is the function I use that creates the initial accounts
public static void createAccounts(CrimsHRData crimsData){
try {
//try to create a new account - loop this code for all valid USIS users creating an account for each
if (!crimsData.users.isEmpty()){
System.out.println(crimsData.users.size()+" users to create.");
for (int i=0; i <= crimsData.users.size()-1; i++){ //check if accounts already exists on the server
CrimsHRData.User theUser = (CrimsHRData.User)crimsData.users.get(i);
conn2 = new XMPPConnection(OPENIMSERVER, OPENIMSERVERPORT);
try {
//if this works then the account already exists
conn2.login(theUser.networkLogin, OPENIMGLOBALUSERPASSWORD);
conn2.getRoster().setSubscriptionMode(Roster.SUBSCRIPTION_MANUAL);
System.out.println(theUser.networkLogin+" Account Exists!");
conn2.close();
}
catch (XMPPException ex) {
//if this doesn''t work then the account may not exist so lets create it
conn2.close();
conn2 = new XMPPConnection(OPENIMSERVER, OPENIMSERVERPORT);
conn2.getAccountManager().createAccount(theUser.networkLogin,OPENIMGLOBALUSERPASSWORD);
//conn2.getRoster().setSubscriptionMode(Roster.SUBSCRIPTION_MANUAL);
System.out.println(theUser.networkLogin+" Account Created!");
conn2.close();
} }
} else {
System.out.println("No users to create.");
} }
catch (XMPPException ex) {
ex.printStackTrace();
}
}
Here is the CrimsHRData class that I pass to these functions…
public class CrimsHRData implements Const {
SqlConnection sqlConn;
ResultSet rs;
String className; public User user; public class User {
public int employeeID;
public int supervisor;
public String employeeName;
public String position;
public String department;
public String returnEmail;
public String networkLogin;
} public ArrayList users;
public ArrayList groups; public CrimsHRData() {
//tell the logger where we are at and set the opening vars
className = this.getClass().getName(); //do sql here
sqlConn = new SqlConnection(); //do other create code here
GetUsers();
GetGroups(); //clean up here
sqlConn.closeConnection();
} public void GetUsers(){
//get the users here
users = new ArrayList(); //read the info from the tables for the selected valid searchid
try {
Statement stmt = sqlConn.getConnection().createStatement();
rs = stmt.executeQuery(sqlGetUsers); //loop the record set and add to the users list
while (rs.next()) {
user = new User();
user.employeeID = rs.getInt("employeeidreal");
user.supervisor = rs.getInt("mysupervisor");
user.employeeName = rs.getString("employee");
user.position = rs.getString("position");
user.department = rs.getString("department");
user.returnEmail = rs.getString("returnEmail");
user.networkLogin = rs.getString("networkLogin");
users.add(user);
}
stmt = null;
rs.close();
}
catch (SQLException ex) {
ex.printStackTrace();
}
} public void GetGroups(){
//get the current groups here
groups = new ArrayList(); //read the info from the tables for the selected valid searchid
try {
Statement stmt = sqlConn.getConnection().createStatement();
rs = stmt.executeQuery(sqlGetGroups); //loop the record set and add to the users list
while (rs.next()) {
String group;
group = rs.getString("department");
groups.add(group);
}
stmt = null;
rs.close();
}
catch (SQLException ex) {
ex.printStackTrace();
}
} //end of class }
Michael,
I’'ve been reviewing your code and I have a couple of comments and questions.
Comments:
-
Next time you can post your code between these tags … /c o d e but without the spaces. If you want you can edit your previous posts
-
There is no need to check for the user’‘s group and create the missing ones since an empty group won’'t be saved in the server. Removing this check makes the code a lot simpler.
So your code would look something like:
// ok now that all the accounts have been created login as each of those accounts and edit the roster and groups
CrimsHRData.User theUser; if (!crimsData.users.isEmpty()) {
for (int i = 0; i <= crimsData.users.size() - 1; i++) {
conn2 = new XMPPConnection(OPENIMSERVER, OPENIMSERVERPORT); theUser = (CrimsHRData.User) crimsData.users.get(i); // next login as each of the above users after all accounts have been created
conn2.login(theUser.networkLogin, OPENIMGLOBALUSERPASSWORD);
conn2.getRoster().setSubscriptionMode(Roster.SUBSCRIPTION_MANUAL);
System.out.println("--- Logged In As: " + theUser.networkLogin + " ---");
Roster roster = conn2.getRoster(); // add users to the roster in the perspective groups
for (int u = 0; u <= crimsData.users.size() - 1; u++) {
// get the current user item here theRosterAddition
CrimsHRData.User theRosterAddition =
(CrimsHRData.User) crimsData.users.get(u); // the user doesn''t exist so lets create it
if (!theRosterAddition
.networkLogin
.equalsIgnoreCase(theUser.networkLogin)) {
String[] groups = { theRosterAddition.department };
roster.createEntry(
theRosterAddition.networkLogin + "@" + OPENIMSERVER,
theRosterAddition.employeeName,
groups);
System.out.println(
"Added Roster: "
+ theRosterAddition.networkLogin
+ "@"
+ OPENIMSERVER);
}
}
// close connection
conn2.close();
}
}
System.out.println("--- Accounts Create Done! ---");
Questions:
-
When you refer to “General” group, are you refering to a group called General or to unfiled entries?
-
If you are refering to a group called General then the explanation that I have is that theRosterAddition.department has the “General” String value. I’'ll need you to post the transmitted XML to the server (copy this info from the debugger window)
-
If you are refering to unfiled entries then theRosterAddition.department is null
– Gato
OpenIM released a new version that uses xml config files… thus making it much easier to configure and pre-populate accounts and roster lists! So I just built a tool to work with the xml on the server! I’'m now rockin and rolling! Thanks for the help!
Can you send your openim database class source code to me?! Please!!!
Thanks!!
mail:smoking_boy@msn.com