/*
* Tigase Jabber/XMPP Server
* Copyright (C) 2004-2012 "Artur Hefczyc" <artur.hefczyc@tigase.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. Look for COPYING file in the top folder.
* If not, see http://www.gnu.org/licenses/.
*
* $Rev$
* Last modified by $Author$
* $Date$
*/
package tigase.util;
//~--- non-JDK imports --------------------------------------------------------
import tigase.db.RepositoryFactory;
import tigase.db.AuthRepository;
import tigase.db.UserExistsException;
import tigase.db.UserRepository;
import tigase.xmpp.BareJID;
import tigase.xmpp.JID;
import tigase.xmpp.impl.roster.RosterAbstract;
//~--- JDK imports ------------------------------------------------------------
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.Writer;
import java.util.List;
//~--- classes ----------------------------------------------------------------
/**
* Describe class RepositoryUtils here.
*
*
* Created: Sat Oct 28 13:09:26 2006
*
* @author <a href="mailto:artur.hefczyc@tigase.org">Artur Hefczyc</a>
* @version $Rev$
*/
public class RepositoryUtils {
private static long counter = 0;
private static BareJID user1 = BareJID.bareJIDInstanceNS("user111@hostname");
private static BareJID user2 = BareJID.bareJIDInstanceNS("user222@hostname");
private static BareJID user3 = BareJID.bareJIDInstanceNS("user333@hostname");
private static String src_class = "tigase.db.jdbc.JDBCRepository";
private static String src_uri = null;
private static String dst_class = null;
private static String dst_uri = null;
private static String content = null;
private static BareJID user = null;
private static boolean simple_test = false;
private static boolean add_user_test = false;
private static boolean copy_repos = false;
private static boolean print_repo = false;
private static boolean add = false;
private static boolean del = false;
private static boolean node = false;
private static boolean key_val = false;
private static boolean check_roster = false;
private static boolean allowed_empty_groups = true;
private static boolean import_data = false;
private static boolean export_data = false;
private static String subnode = null;
private static String key = null;
private static String value = null;
private static String import_file = null;
private static String export_file = null;
//~--- methods --------------------------------------------------------------
//public static boolean checkJID(JID jid) {
// String nick_check = JIDUtils.checkNickName(JIDUtils.getNodeNick(jid));
// if (nick_check != null) {
// System.out.println(" Invalid nickname - " + JIDUtils.getNodeNick(jid)
// + ": " + nick_check);
// return false;
// }
// String host_check = JIDUtils.checkNickName(JIDUtils.getNodeHost(jid));
// if (host_check != null) {
// System.out.println(" Invalid hostname - " + JIDUtils.getNodeHost(jid)
// + ": " + host_check);
// return false;
// }
// return true;
//}
/**
* Method description
*
*
* @param user
* @param repo
* @param cont
*
* @return
*
* @throws Exception
*/
public static boolean checkContact(BareJID user, UserRepository repo, String cont)
throws Exception {
// String[] keys = repo.getKeys(user, "roster/"+contact);
JID contact = JID.jidInstanceNS(cont);
String[] vals = repo.getDataList(user, "roster/" + contact, RosterAbstract.GROUPS);
if ((vals == null) || (vals.length == 0)) {
System.out.println(" Empty groups list");
if ( !allowed_empty_groups) {
return false;
}
} else {
for (String val : vals) {
if (val.equals("Upline Support") || val.equals("Support") || val.startsWith("Level ")) {
System.out.println(" Invalid group: " + val);
return false;
}
}
}
return true;
}
/**
* Method description
*
*
* @param user
* @param node
* @param src
* @param dst
*
* @throws Exception
*/
public static void copyNode(BareJID user, String node, UserRepository src, UserRepository dst)
throws Exception {
String[] keys = src.getKeys(user, node);
if (keys != null) {
for (String key : keys) {
String[] vals = src.getDataList(user, node, key);
if (vals != null) {
dst.setDataList(user, node, key, vals);
} // end of if (vals != null) else
} // end of for (String key: keys)
} // end of if (keys != null)
String[] nodes = src.getSubnodes(user, node);
if (nodes != null) {
for (String subnode : nodes) {
copyNode(user, ((node != null) ? node + "/" + subnode : subnode), src, dst);
} // end of for (String node: nodes)
} // end of if (ndoes != null)
}
/**
* Method description
*
*
* @param src
* @param dst
*
* @throws Exception
*/
public static void copyRepositories(UserRepository src, UserRepository dst) throws Exception {
if (user != null) {
copyUser(user, src, dst);
} else {
List<BareJID> users = src.getUsers();
if (users != null) {
System.out.println("Found " + users.size() + " in the source repository.");
for (BareJID usr : users) {
System.out.println("Found " + usr + " in the source repository.");
copyUser(usr, src, dst);
} // end of for (String user: users)
} else {
System.out.println("There are no user accounts in source repository.");
} // end of else
} // end of if (user != null) else
}
/**
* Method description
*
*
* @param src
* @param dst
*
* @throws Exception
*/
public static void copyRepositories(UserRepository src, AuthRepository dst) throws Exception {
if (user != null) {
copyUser(user, src, dst);
} else {
List<BareJID> users = src.getUsers();
if (users != null) {
for (BareJID usr : users) {
copyUser(usr, src, dst);
} // end of for (String user: users)
} else {
System.out.println("There are no user accounts in source repository.");
} // end of else
} // end of if (user != null) else
}
/**
* Method description
*
*
* @param user
* @param src
* @param dst
*
* @throws Exception
*/
public static void copyUser(BareJID user, UserRepository src, UserRepository dst)
throws Exception {
if (user == null) {
return;
}
System.out.print("Copying user: " + user + "...");
try {
dst.addUser(user);
copyNode(user, null, src, dst);
System.out.println("OK");
} catch (UserExistsException e) {
System.out.println("ERROR, user already exists.");
}
}
/**
* Method description
*
*
* @param user
* @param src
* @param dst
*
* @throws Exception
*/
public static void copyUser(BareJID user, UserRepository src, AuthRepository dst)
throws Exception {
if ((user == null)) {
return;
}
System.out.print("Copying user: " + user + "...");
String password = src.getData(user, "password");
try {
dst.addUser(user, password);
System.out.println("OK");
} catch (UserExistsException e) {
System.out.println("ERROR, user already exists.");
}
}
/**
* Method description
*
*
* @param repo
* @param w
*
* @throws Exception
*/
public static void exportRoster(UserRepository repo, Writer w) throws Exception {
if (user != null) {
exportUserRoster(user, repo, w);
} else {
List<BareJID> users = repo.getUsers();
if (users != null) {
for (BareJID usr : users) {
// System.out.println(usr);
exportUserRoster(usr, repo, w);
} // end of for (String user: users)
} else {
System.out.println("There are no user accounts in repository.");
} // end of else
}
}
/**
* Method description
*
*
* @param user
* @param repo
* @param w
*
* @throws Exception
*/
public static void exportUserRoster(BareJID user, UserRepository repo, Writer w)
throws Exception {
System.out.println(" " + (++counter) + ". " + user + " roster: ");
String[] contacts = repo.getSubnodes(user, "roster");
if (contacts != null) {
for (String contact : contacts) {
System.out.println(" contact: " + contact);
boolean valid = checkContact(user, repo, contact);
if (valid) {
System.out.println(" looks OK");
String password = repo.getData(user, "password");
String[] groups = repo.getDataList(user, "roster/" + contact, RosterAbstract.GROUPS);
String contact_nick = repo.getData(user, "roster/" + contact, RosterAbstract.NAME);
String subscription = repo.getData(user, "roster/" + contact,
RosterAbstract.SUBSCRIPTION);
StringBuilder sb = new StringBuilder(user.toString());
sb.append(",");
if (password != null) {
sb.append(password);
}
sb.append("," + contact);
sb.append(",");
if (contact_nick != null) {
sb.append(contact_nick);
}
sb.append(",");
if (subscription != null) {
sb.append(subscription);
}
if ((groups != null) && (groups.length > 0)) {
for (String group : groups) {
sb.append("," + group);
}
}
sb.append("\n");
w.write(sb.toString());
} else {
System.out.println(" should be REMOVED");
String contact_node = "roster/" + contact;
System.out.println(" removing node: " + contact_node);
// repo.removeSubnode(user, contact_node);
System.out.println(" DONE.");
}
} // end of for (String node: nodes)
} else {
System.out.println(" empty roster...");
}
}
/**
* Method description
*
*
* @param repo
*
* @throws Exception
*/
public static void loadTestData(UserRepository repo) throws Exception {
try {
repo.addUser(user1);
} catch (UserExistsException e) {}
try {
repo.addUser(user2);
} catch (UserExistsException e) {}
try {
repo.addUser(user3);
} catch (UserExistsException e) {}
repo.setData(user1, null, "password", "secret111");
repo.setData(user2, null, "password", "secret222");
repo.setData(user3, null, "password", "secret333");
repo.setData(user1, "roster/buddy111", "name", "budy1");
repo.setData(user1, "roster/buddy222", "name", "budy2");
repo.setData(user1, "roster/buddy333", "name", "budy3");
repo.setDataList(user1, "roster/buddy111", "groups", new String[] { "buddies", "friends" });
repo.setDataList(user2, "roster/buddy111", "groups", new String[] { "buddies", "friends" });
repo.addDataList(user2, "roster/buddy111", "groups", new String[] { "family", "home" });
}
/**
* Describe <code>main</code> method here.
*
* @param args a <code>String[]</code> value
*
* @throws Exception
*/
public static void main(final String[] args) throws Exception {
parseParams(args);
Exception repo_exc = null;
UserRepository src_repo = null;
AuthRepository src_auth = null;
try {
src_repo = RepositoryFactory.getUserRepository(src_class, src_uri, null);
System.out.println("Loaded src_repo " + src_repo.getClass().getName() + " for parameters:"
+ "\n src_class=" + src_class + "\n src_uri=" + src_uri);
} catch (Exception e) {
repo_exc = e;
src_repo = null;
} // end of try-catch
// Unsuccessful UserRepository initialization
// Let's try with AuthRepository....
if (src_repo == null) {
try {
src_auth = RepositoryFactory.getAuthRepository(src_class, src_uri, null);
System.out.println("Loaded src_auth " + src_auth.getClass().getName() + " for parameters:"
+ "\n src_class=" + src_class + "\n src_uri=" + src_uri);
} catch (Exception e) {
System.out.println("Incorrect source class name given (or connection URI).");
System.out.println("class: " + src_class);
System.out.println("uri: " + src_uri);
System.out.println("Can't initialize repository:");
repo_exc.printStackTrace();
e.printStackTrace();
System.exit(-1);
} // end of try-catch
} // end of if (src_repo == null)
if (simple_test) {
System.out.println("Simple test on repository:");
simpleTest(src_repo);
} // end of if (simple_test)
if (add_user_test) {
System.out.println("Simple test on repository:");
userAddTest(src_repo);
} // end of if (simple_test)
if (add) {
if (key_val && (src_repo != null)) {
System.out.println("Adding key=value: " + content);
parseNodeKeyValue(content);
System.out.println("Parsed parameters: user=" + user + ", node=" + subnode + ", key=" + key
+ ", value=" + value);
src_repo.setData(user, subnode, key, value);
} else {
System.out.println("Adding user: " + user);
if (src_repo != null) {
src_repo.addUser(user);
}
if (src_auth != null) {
BareJID name = user;
String password = "";
src_auth.addUser(name, password);
}
} // end of else
} // end of if (add)
if (del) {
if (key_val || node) {
if (key_val) {
System.out.println("Deleting data: " + content);
parseNodeKeyValue(content);
System.out.println("Parsed parameters: user=" + user + ", node=" + subnode + ", key="
+ key + ", value=" + value);
src_repo.removeData(user, subnode, key);
} // end of if (key_val)
if (node) {
System.out.println("Deleting data node: " + content);
src_repo.removeSubnode(user, content);
} // end of if (node)
} else {
System.out.println("Deleting user: " + user);
if (src_repo != null) {
src_repo.removeUser(user);
}
if (src_auth != null) {
src_auth.removeUser(user);
}
} // end of else
} // end of if (del)
if (copy_repos) {
UserRepository dst_repo = null;
Exception dst_exc = null;
AuthRepository dst_auth = null;
try {
dst_repo = RepositoryFactory.getUserRepository(dst_class, dst_uri, null);
System.out.println("Loaded dst_repo " + dst_repo.getClass().getName() + " for parameters:"
+ "\n src_class=" + dst_class + "\n src_uri=" + dst_uri);
copyRepositories(src_repo, dst_repo);
} catch (Exception e) {
dst_exc = e;
dst_repo = null;
} // end of try-catch
if (dst_repo == null) {
try {
dst_auth = RepositoryFactory.getAuthRepository(dst_class, dst_uri, null);
System.out.println("Loaded dst_auth " + dst_auth.getClass().getName()
+ " for parameters:" + "\n src_class=" + dst_class + "\n src_uri=" + dst_uri);
} catch (Exception e) {
System.out.println("Incorrect destination class name given (or connection URI).");
System.out.println("Can't initialize repository:");
dst_exc.printStackTrace();
e.printStackTrace();
System.exit(-1);
} // end of try-catch
copyRepositories(src_repo, dst_auth);
} // end of if (dst_repo == null)
} // end of if (copy_repos)
if (check_roster && (src_repo != null)) {
System.out.println("Checking roster:");
if (user != null) {
repairUserRoster(user, src_repo);
} else {
repairRoster(src_repo);
} // end of else
}
if (import_data && (src_repo != null)) {
BufferedReader br = new BufferedReader(new FileReader(import_file));
String line = null;
while ((line = br.readLine()) != null) {
String[] vals = line.split(",");
BareJID userId = BareJID.bareJIDInstance(vals[0].trim());
try {
src_repo.addUser(userId);
} catch (UserExistsException e) {}
if ((vals.length >= 2) && (vals[1].trim().length() > 0)) {
src_repo.setData(userId, null, "password", vals[1].trim());
}
if ((vals.length >= 3) && (vals[2].trim().length() > 0)) {
src_repo.setData(userId, "roster/" + vals[2].trim(), "name", vals[2].trim());
}
if ((vals.length >= 4) && (vals[3].trim().length() > 0)) {
src_repo.setData(userId, "roster/" + vals[2].trim(), "name", vals[3].trim());
}
if ((vals.length >= 5) && (vals[4].trim().length() > 0)) {
src_repo.setData(userId, "roster/" + vals[2].trim(), "subscription", vals[4].trim());
}
if ((vals.length >= 6) && (vals[5].trim().length() > 0)) {
src_repo.setData(userId, "roster/" + vals[2].trim(), "groups", vals[5].trim());
}
}
br.close();
}
if (export_data && (src_repo != null)) {
FileWriter fr = new FileWriter(export_file);
if (user != null) {
exportUserRoster(user, src_repo, fr);
} else {
exportRoster(src_repo, fr);
} // end of else
fr.close();
}
if (print_repo && (src_repo != null)) {
System.out.println("Printing repository:");
if (content != null) {
if (node) {
subnode = content;
} else {
parseNodeKeyValue(content);
}
} // end of if (content != null)
if (user != null) {
if (key_val) {
System.out.println(src_repo.getData(user, subnode, key, null));
} else {
if (node) {
printNode(user, src_repo, " ", subnode);
} else {
printNode(user, src_repo, "", null);
} // end of else
} // end of else
} else {
printRepoContent(src_repo);
} // end of else
} // end of if (print_repo)
}
/**
* Method description
*
*
* @param args
*
* @throws TigaseStringprepException
*/
public static void parseParams(final String[] args) throws TigaseStringprepException {
if ((args != null) && (args.length > 0)) {
for (int i = 0; i < args.length; i++) {
if (args[i].equals("-h")) {
System.out.print(help());
System.exit(0);
} // end of if (args[i].equals("-h"))
if (args[i].equals("-sc")) {
src_class = args[++i];
} // end of if (args[i].equals("-h"))
if (args[i].equals("-su")) {
src_uri = args[++i];
} // end of if (args[i].equals("-h"))
if (args[i].equals("-dc")) {
dst_class = args[++i];
} // end of if (args[i].equals("-h"))
if (args[i].equals("-du")) {
dst_uri = args[++i];
} // end of if (args[i].equals("-h"))
if (args[i].equals("-dt")) {
content = args[++i];
} // end of if (args[i].equals("-h"))
if (args[i].equals("-st")) {
simple_test = true;
} // end of if (args[i].equals("-h"))
if (args[i].equals("-at")) {
add_user_test = true;
} // end of if (args[i].equals("-h"))
if (args[i].equals("-cp")) {
copy_repos = true;
} // end of if (args[i].equals("-h"))
if (args[i].equals("-pr")) {
print_repo = true;
} // end of if (args[i].equals("-h"))
if (args[i].equals("-u")) {
user = BareJID.bareJIDInstance(args[++i]);
} // end of if (args[i].equals("-h"))
if (args[i].equals("-n")) {
node = true;
} // end of if (args[i].equals("-h"))
if (args[i].equals("-kv")) {
key_val = true;
} // end of if (args[i].equals("-h"))
if (args[i].equals("-add")) {
add = true;
} // end of if (args[i].equals("-h"))
if (args[i].equals("-del")) {
del = true;
} // end of if (args[i].equals("-h"))
if (args[i].equals("-roster")) {
check_roster = true;
} // end of if (args[i].equals("-h"))
if (args[i].equals("-import")) {
import_data = true;
import_file = args[++i];
} // end of if (args[i].equals("-h"))
if (args[i].equals("-export")) {
export_data = true;
export_file = args[++i];
} // end of if (args[i].equals("-h"))
if (args[i].equals("-aeg")) {
allowed_empty_groups = args[++i].equals("true");
} // end of if (args[i].equals("-h"))
} // end of for (int i = 0; i < args.length; i++)
}
}
/**
* Method description
*
*
* @param user
* @param repo
* @param prefix
* @param node
*
* @throws Exception
*/
public static void printNode(BareJID user, UserRepository repo, String prefix, String node)
throws Exception {
if (node != null) {
System.out.println(prefix + "node: " + node);
} // end of if (node != null)
String[] keys = repo.getKeys(user, node);
if (keys != null) {
for (String key : keys) {
String[] vals = repo.getDataList(user, node, key);
if (vals != null) {
StringBuilder valstr = new StringBuilder();
for (String val : vals) {
valstr.append(" ").append(val);
} // end of for (String val: vals)
System.out.println(prefix + " " + key + " = " + valstr);
} else {
System.out.println(" " + key);
} // end of if (vals != null) else
} // end of for (String key: keys)
} // end of if (keys != null)
String[] nodes = repo.getSubnodes(user, node);
if (nodes != null) {
for (String subnode : nodes) {
printNode(user, repo, prefix + " ", ((node != null) ? node + "/" + subnode : subnode));
} // end of for (String node: nodes)
} // end of if (ndoes != null)
}
/**
* Method description
*
*
* @param repo
*
* @throws Exception
*/
public static void printRepoContent(UserRepository repo) throws Exception {
if (user != null) {
printNode(user, repo, " ", subnode);
} else {
List<BareJID> users = repo.getUsers();
if (users != null) {
for (BareJID usr : users) {
System.out.println(usr);
printNode(usr, repo, " ", subnode);
} // end of for (String user: users)
} else {
System.out.println("There are no user accounts in repository.");
} // end of else
}
}
/**
* Method description
*
*
* @param repo
*
* @throws Exception
*/
public static void removeTestData(UserRepository repo) throws Exception {
repo.removeUser(user1);
repo.removeUser(user2);
repo.removeUser(user3);
}
/**
* Method description
*
*
* @param repo
*
* @throws Exception
*/
public static void repairRoster(UserRepository repo) throws Exception {
if (user != null) {
repairUserRoster(user, repo);
} else {
List<BareJID> users = repo.getUsers();
if (users != null) {
for (BareJID usr : users) {
// System.out.println(usr);
repairUserRoster(usr, repo);
} // end of for (String user: users)
} else {
System.out.println("There are no user accounts in repository.");
} // end of else
}
}
/**
* Method description
*
*
* @param user
* @param repo
*
* @throws Exception
*/
public static void repairUserRoster(BareJID user, UserRepository repo) throws Exception {
System.out.println(" " + (++counter) + ". " + user + " roster: ");
String[] contacts = repo.getSubnodes(user, "roster");
if (contacts != null) {
for (String contact : contacts) {
System.out.println(" contact: " + contact);
boolean valid = checkContact(user, repo, contact);
if (valid) {
System.out.println(" looks OK");
} else {
System.out.println(" should be REMOVED");
String contact_node = "roster/" + contact;
System.out.println(" removing node: " + contact_node);
repo.removeSubnode(user, contact_node);
System.out.println(" DONE.");
}
} // end of for (String node: nodes)
} else {
System.out.println(" empty roster...");
}
}
/**
* Method description
*
*
* @param repo
*
* @throws Exception
*/
public static void simpleTest(UserRepository repo) throws Exception {
printRepoContent(repo);
try {
repo.addUser(user1);
} catch (UserExistsException e) {}
printRepoContent(repo);
removeTestData(repo);
printRepoContent(repo);
}
/**
* Method description
*
*
* @param re
*
* @throws Exception
*/
public static void userAddTest(UserRepository re) throws Exception {
AuthRepository repo = (AuthRepository) re;
BareJID test_user = BareJID.bareJIDInstanceNS("test111@localhost");
printRepoContent(re);
try {
repo.addUser(test_user, "some-pass");
} catch (UserExistsException e) {
e.printStackTrace();
}
printRepoContent(re);
System.out.println(re.getData(test_user, "privacy", "default-list", null));
repo.removeUser(test_user);
printRepoContent(re);
}
private static String help() {
return "\n" + "Parameters:\n" + " -h this help message\n"
+ " -sc class source repository class name\n"
+ " -su uri source repository init string\n"
+ " -dc class destination repository class name\n"
+ " -du uri destination repository init string\n"
+ " -dt string data content to set/remove in repository\n"
+ " -u user user ID, if given all operations are only for that ID\n"
+ " if you want to add user to AuthRepository parameter must\n"
+ " in form: \"user:password\"\n"
+ " -st perform simple test on repository\n"
+ " -at simple test for adding and removing user\n"
+ " -cp copy content from source to destination repository\n"
+ " -pr print content of the repository\n"
+ " -n data content string is a node string\n"
+ " -kv data content string is node/key=value string\n"
+ " -add add data content to repository\n"
+ " -del delete data content from repository\n" + " ------------\n"
+ " -roster check the user roster\n"
+ " -aeg [true|false] Allow empty group list for the contact\n"
+ " -import file import user data from the file of following format:\n"
+ " user_jid, password, roser_jid, roster_nick, subscription, group\n"
+ " -export file export user roster data to the specified file in the following\n"
+ " format: user_jid, password, roser_jid, roster_nick, subscription,\n"
+ " group\n" + "\n" + "\n"
+ "Note! If you put UserAuthRepository implementation as a class name\n"
+ " some operation are not allowed and will be silently skipped.\n"
+ " Have a look at UserAuthRepository to see what operations are\n"
+ " possible or what operation does make sense.\n"
+ " Alternatively look for admin tools guide on web site.\n"
;
}
private static void parseNodeKeyValue(String data) {
int val_idx = data.indexOf('=');
value = data.substring(val_idx + 1);
String tmp_str = data.substring(0, val_idx);
int key_idx = tmp_str.lastIndexOf('/');
if (key_idx >= 0) {
key = tmp_str.substring(key_idx + 1);
subnode = tmp_str.substring(0, key_idx);
} // end of if (key_idx >= 0)
else {
key = tmp_str;
} // end of if (key_idx >= 0) else
}
} // RepositoryUtils
//~ Formatted in Sun Code Convention
//~ Formatted by Jindent --- http://www.jindent.com