Commit 1776b9e4 authored by Ryan Graham's avatar Ryan Graham Committed by ryang

* Added the ability to allow users to specify the import and export file locations

* JM-369
* Added additional information to the migration section of the readme file

git-svn-id: http://svn.igniterealtime.org/svn/repos/messenger/trunk@2755 b35dd754-fafc-0310-a699-88a17e54d16e
parent 7e45a0a4
......@@ -2,41 +2,46 @@
<html>
<head>
<title>User Import/Export Plugin Changelog</title>
<style type="text/css">
BODY {
font-size : 100%;
}
BODY, TD, TH {
font-family : tahoma, verdana, arial, helvetica, sans-serif;
font-size : 0.8em;
}
H2 {
font-size : 10pt;
font-weight : bold;
padding-left : 1em;
}
A:hover {
text-decoration : none;
}
H1 {
font-family : tahoma, arial, helvetica, sans-serif;
font-size : 1.4em;
font-weight: bold;
border-bottom : 1px #ccc solid;
padding-bottom : 2px;
}
<title>User Import/Export Plugin Changelog</title>
<style type="text/css">
BODY {
font-size : 100%;
}
BODY, TD, TH {
font-family : tahoma, verdana, arial, helvetica, sans-serif;
font-size : 0.8em;
}
H2 {
font-size : 10pt;
font-weight : bold;
padding-left : 1em;
}
A:hover {
text-decoration : none;
}
H1 {
font-family : tahoma, arial, helvetica, sans-serif;
font-size : 1.4em;
font-weight: bold;
border-bottom : 1px #ccc solid;
padding-bottom : 2px;
}
TT {
font-family : courier new;
font-weight : bold;
color : #060;
}
PRE {
font-family : courier new;
font-size : 100%;
}
</style>
TT {
font-family : courier new;
font-weight : bold;
color : #060;
}
PRE {
font-family : courier new;
font-size : 100%;
}
</style>
</head>
<body>
......@@ -44,11 +49,18 @@
User Import/Export Plugin Changelog
</h1>
<p><b>2.0</b> -- September 1, 2005</p>
<ul>
<li>Added the ability to allow users to specify the import and export file locations.
<li>[<a href="http://www.jivesoftware.org/issues/browse/JM-369">JM-369</a>] - Add option to replace old domain with new domain while doing an import.
<li>Added additional information to the migration section of the readme file.
</ul>
<p><b>1.0.1</b> -- June 30, 2005</p>
<ul>
<li>Added the ability to send export data directly to the screen.</li>
<li>Fixed compatibility issue with Messenger version 2.1.4 and 2.1.5.</li>
<li>Refactored the code that creates the output directory to try and alleviate permission issues on Unix installations.</li>
<li>Added the ability to send export data directly to the screen.</li>
<li>Fixed compatibility issue with Messenger version 2.1.4 and 2.1.5.</li>
<li>Refactored the code that creates the output directory to try and alleviate permission issues on Unix installations.</li>
</ul>
<p><b>1.0</b> -- June 1, 2005</p>
......
<?xml version="1.0" encoding="UTF-8"?>
<plugin>
<class>org.jivesoftware.messenger.plugin.ImportExportPlugin</class>
<class>org.jivesoftware.messenger.plugin.ImportExportPlugin</class>
<name>User Import Export</name>
<description>Enables import and export of user data.</description>
<author>Ryan Graham</author>
<version>1.0.1</version>
<date>06/30/2005</date>
<minServerVersion>2.1.4</minServerVersion>
<description>Enables import and export of user data.</description>
<author>Ryan Graham</author>
<version>2.0</version>
<date>09/01/2005</date>
<minServerVersion>2.1.5</minServerVersion>
<adminconsole>
<tab id="tab-users">
<adminconsole>
<tab id="tab-users">
<sidebar id="user-import-export" name="Import &amp; Export">
<item id="import-export-selection" name="User Import &amp; Export"
url="import-export-selection.jsp"
description="Allows the importing and exporting of Messenger user data." />
</sidebar>
</tab>
</adminconsole>
</plugin>
\ No newline at end of file
url="import-export-selection.jsp"
description="Allows the importing and exporting of Messenger user data." />
</sidebar>
</tab>
</adminconsole>
</plugin>
......@@ -2,89 +2,284 @@
<html>
<head>
<title>User Import/Export Plugin Readme</title>
<style type="text/css">
BODY {
font-size : 100%;
}
BODY, TD, TH {
font-family : tahoma, verdana, arial, helvetica, sans-serif;
font-size : 0.8em;
}
H2 {
font-size : 10pt;
font-weight : bold;
}
A:hover {
text-decoration : none;
}
H1 {
font-family : tahoma, arial, helvetica, sans-serif;
font-size : 1.4em;
font-weight: bold;
border-bottom : 1px #ccc solid;
padding-bottom : 2px;
}
TT {
font-family : courier new;
font-weight : bold;
color : #060;
}
PRE {
font-family : courier new;
font-size : 100%;
}
</style>
<title>User Import/Export Plugin Readme</title>
<style type="text/css">
BODY {
font-size : 100%;
}
BODY, TD, TH {
font-family : tahoma, verdana, arial, helvetica, sans-serif;
font-size : 0.8em;
}
H2 {
font-size : 11pt;
font-weight : bold;
}
A:hover {
text-decoration : none;
}
H1 {
font-family : tahoma, arial, helvetica, sans-serif;
font-size : 1.4em;
font-weight: bold;
border-bottom : 1px #ccc solid;
padding-bottom : 2px;
}
TT {
font-family : courier new;
font-weight : bold;
color : #060;
}
PRE {
font-family : courier new;
font-size : 100%;
}
#datatable TH {
color : #fff;
background-color : #2A448C;
text-align : left;
}
#datatable TD {
background-color : #FAF6EF;
}
#datatable .name {
background-color : #DCE2F5;
text-align : center;
}
</style>
</head>
<body>
<h1>User Import/Export Plugin Readme</h1>
<h2>Overview</h2>
<p>The user import/export plugin provides a way to import and export Jive Messenger
user data via the Admin Console. The user data consists of jid (aka "username"),
name, email address, password and roster list (aka "buddy list"). This plugin also
can aid in the migration of users from other Jabber/XMPP based systems to Jive
Messenger.</p>
<p>The user import/export plugin provides a way to import and export Jive Messenger user data via
the Admin Console. The user data consists of jid (aka "username"), name, email address, password
and roster list (aka "buddy list"). This plugin also can aid in the migration of users from other
Jabber/XMPP based systems to Jive Messenger.</p>
<h2>Installation</h2>
<p>Copy the userImportExport.jar into the plugins directory of your Jive Messenger
installation. The plugin will then be automatically deployed. To upgrade to a new
version, copy the new userImportExport.jar file over the existing file.</p>
<p>Copy the userImportExport.jar into the plugins directory of your Jive Messenger installation.
The plugin will then be automatically deployed. To upgrade to a new version, copy the new
userImportExport.jar file over the existing file.</p>
<h2>Configuration</h2>
<p>Presently, there is nothing that can be configured for the user import/export plugin.</p>
<h2>Using the Plugin</h2>
<p> The plugin is accessed via the "User Import & Export" sidebar item located under
the "Users/Groups" tab in the Admin Console. Note: if you are using LDAP as your user
data source the following message will appear: "Sorry, because you are using LDAP as
your user store this plugin will not work with your Messenger installation."
<li>Importing - Select the "Import User Data" option from the user import/export
selection page. On the import page, notice that the plugin will look for user data
import files in the MESSENGER_HOME/export directory. In the "Import File Name" field,
enter the name of the file you want import from and then click on the "Import" button.
If the plugin is successful in importing all user data, you will be presented with the
message: "All users added successfully" If the plugin was not successful in importing
all user data you, will receive a message indicating what might have gone wrong. If
during the import process, the plugin detects that you are trying to import a user
that already exists in the system, it will not import that user or any roster
<p>The plugin is accessed via the "User Import & Export" sidebar item located under the
"Users/Groups" tab in the Admin Console. Note: if you are using LDAP as your user data source the
following message will appear: "Sorry, because you are using LDAP as your user store this plugin
will not work with your Messenger installation."
<li><b>Importing</b> - Select the "Import User Data" option from the user import/export selection
page. On the import page, use the "Browse" button to locate the file that contains the user
information you want to locate and then click on the "Import" button. If the plugin is successful
in importing all user data, you will be presented with the message: "All users added successfully".
If the plugin was not successful in importing all user data you, will receive a message indicating
what might have gone wrong. If during the import process, the plugin detects that you are trying to
import a user that already exists in the system, it will not import that user or any roster
information.</li>
<li>Exporting - Select the "Export User Data" option from the user import/export
selection page. User data can be exported either to a file or directly to the screen.
To export to a file, select the "To File" radio button. Notice that the plugin will
export user data to the MESSENGER_HOME/export directory. In the "Export File Name"
field, enter the name of the file you want export to and then click on the "Export"
button. Note: the plugin will automatically append an ".xml" extension to the file
name if it is not already present. To export to the screen, select the "To Screen"
radio button and then click on the "Export" button. The user data will be placed in
<br>
<li><b>Exporting</b> - Select the "Export User Data" option from the user import/export selection
page. User data can be exported either to a file or directly to the screen. To export to a file,
select the "To File" radio button, enter the name you want your export file to be called in the
"Export File Name" and then click on the "Export" button. Note: the plugin will automatically append
an ".xml" extension to the file name if it is not already present. To export to the screen, select
the "To Screen" radio button and then click on the "Export" button. The user data will be placed in
the provided text area.</li>
<li>Migration - To import user data from another instant messenger system using the
plugin, the import file must conform to the messenger-user-schema.xsd.xml schema file
(located in the classes directory). When importing a user data file the plugin will
first validate the file against the schema file." If the plugin cannot validate the
import file the user data will not be imported.</li>
<br>
<li><b>Migration</b> - To import user data from another instant messenger system using the plugin,
the import file must conform to the messenger-user-schema.xsd.xml schema file (located in the classes
directory of the userImportExport.jar). When importing a user data file the plugin will first validate
the file against the schema file." If the plugin cannot validate the import file the user data will
not be imported. During the import process the plugin gives you the ability to update user roster
entries domain names to server name of your Messenger installation. For example, say you have a user
whose roster looks like: <br>
<br>
<textarea cols=95 rows=16>
<User>
<Username>mike</Username>
<Password>iamcool</Password>
<Email>mike@mike.com</Email>
<Name>Mike Jones</Name>
<CreationDate>1125442154664</CreationDate>
<ModifiedDate>1125442154664</ModifiedDate>
<Roster>
<Item jid="jane@im.olddomain.net" askstatus="-1" recvstatus="-1" substatus="3" name="Jane">
<Group></Group>
</Item>
<Item jid="paul@xyz.net" askstatus="-1" recvstatus="-1" substatus="3" name="Paul">
<Group></Group>
</Item>
</Roster>
</User>
</textarea>
<br>
<br>
Mike and Jane's accounts both reside on server whose domain name is "im.olddomain.net" and are being
imported to a Messenger installation whose server name is "im.newdomain.net". If on the import screen
the "Optional Existing Domain" field is filled in with "im.olddomain.net" (without the quotes) any
roster item jid that contains "im.olddomain.net" will be replaced with "im.newdomain.net". So, in
effect, the import file would be transformed to look like:
<br>
<br>
<textarea cols=95 rows=16>
<User>
<Username>mike</Username>
<Password>iamcool</Password>
<Email>mike@mike.com</Email>
<Name>Mike Jones</Name>
<CreationDate>1125442154664</CreationDate>
<ModifiedDate>1125442154664</ModifiedDate>
<Roster>
<Item jid="jane@im.newdomain.net" askstatus="-1" recvstatus="-1" substatus="3" name="Jane">
<Group></Group>
</Item>
<Item jid="paul@xyz.net" askstatus="-1" recvstatus="-1" substatus="3" name="Paul">
<Group></Group>
</Item>
</Roster>
</User>
</textarea></li>
</p>
<br>
<br>
Below is a sample of an exported user list from Messenger than contains two users, Joe and Sally, who
have added each other to their respective rosters.
<br>
<br>
<textarea cols=95 rows=16>
<?xml version="1.0" encoding="UTF-8"?>
<JiveMessenger>
<User>
<Username>joe</Username>
<Password>joepwd</Password>
<Email></Email>
<Name></Name>
<CreationDate>1125601449177</CreationDate>
<ModifiedDate>1125601449177</ModifiedDate>
<Roster>
<Item jid="sally@localhost" askstatus="-1" recvstatus="-1" substatus="3" name="Sally">
<Group/>
</Item>
</Roster>
</User>
<User>
<Username>sally</Username>
<Password>sallypwd</Password>
<Email></Email>
<Name></Name>
<CreationDate>1125601471848</CreationDate>
<ModifiedDate>1125601471848</ModifiedDate>
<Roster>
<Item jid="joe@localhost" askstatus="-1" recvstatus="-1" substatus="3">
<Group/>
</Item>
</Roster>
</User>
</JiveMessenger>
</textarea></li>
</p>
<br>
<br>
Below is a list of the different status types and what their associated numbers mean.
<br>
<br>
<div id="datatable">
<table cellpadding="3" cellspacing="1" border="0" width="700">
<thead>
<tr>
<th colspan="2">askstatus</th>
</tr>
</thead>
<tbody>
<tr>
<td class="name">-1</td>
<td>The roster item has no pending subscripton requests.</td>
</tr>
<tr>
<td class="name">0</td>
<td>The roster item has been asked for permission to subscribe to their presence but no
response has been received.</td>
</tr>
<tr>
<td class="name">1</td>
<td>The roster owner has asked to the roster item to unsubscribe from it's presence but
has not received confirmation.</td>
</tr>
</tbody>
</table>
<br>
<table cellpadding="3" cellspacing="1" border="0" width="700">
<thead>
<tr>
<th colspan="2">recvstatus</th>
</tr>
</thead>
<tbody>
<tr>
<td class="name">-1</td>
<td>There are no subscriptions that have been received but not presented to the user.</td>
</tr>
<tr>
<td class="name">1</td>
<td>The server has received a subscribe request, but has not forwarded it to the user.</td>
</tr>
<tr>
<td class="name">2</td>
<td>The server has received an unsubscribe request, but has not forwarded it to the user.</td>
</tr>
</tbody>
</table>
<br>
<table cellpadding="3" cellspacing="1" border="0" width="700">
<thead>
<tr>
<th colspan="2">substatus</th>
</tr>
</thead>
<tbody>
<tr>
<td class="name">-1</td>
<td>Indicates the roster item should be removed.</td>
</tr>
<tr>
<td class="name">0</td>
<td>No subscription is established.</td>
</tr>
<tr>
<td class="name">1</td>
<td>The roster owner has a subscription to the roster item's presence.</td>
</tr>
<tr>
<td class="name">2</td>
<td>The roster item has a subscription to the roster owner's presence.</td>
</tr>
<tr>
<td class="name">3</td>
<td>The roster item and owner have a mutual subscription.</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
package org.jivesoftware.messenger.plugin;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringWriter;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import org.apache.commons.fileupload.FileItem;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
......@@ -30,10 +18,21 @@ import org.jivesoftware.messenger.user.UserAlreadyExistsException;
import org.jivesoftware.messenger.user.UserManager;
import org.jivesoftware.messenger.user.UserNotFoundException;
import org.jivesoftware.messenger.user.UserProvider;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.Log;
import org.xmpp.packet.JID;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
/**
* The user import/export plugin provides a way to import and export Jive Messenger
* user data via the Admin Console. The user data consists of jid (aka "username"),
......@@ -44,37 +43,16 @@ import org.xmpp.packet.JID;
* @author Ryan Graham
*/
public class ImportExportPlugin implements Plugin {
private UserManager userManager;
private UserManager userManager;
private UserProvider provider;
private String serverName;
private String exportDirectory;
public ImportExportPlugin() {
userManager = XMPPServer.getInstance().getUserManager();
provider = UserManager.getUserProvider();
serverName = XMPPServer.getInstance().getServerInfo().getName();
if (exportDirectory == null) {
if (JiveGlobals.getHomeDirectory() != null) {
File messengerHome = new File(JiveGlobals.getHomeDirectory());
if (messengerHome.exists() && messengerHome.canWrite()) {
exportDirectory = (new File(messengerHome, "export")).toString();
}
}
}
if (!exportDirectory.endsWith(File.separator)) {
exportDirectory = exportDirectory + File.separator;
}
// Make sure the export directory exists. If not, make it:
File exportDir = new File(exportDirectory);
if (!exportDir.exists()) {
exportDir.mkdir();
}
}
public void initializePlugin(PluginManager manager, File pluginDirectory) {
......@@ -84,98 +62,56 @@ public class ImportExportPlugin implements Plugin {
userManager = null;
provider = null;
serverName = null;
exportDirectory = null;
}
public boolean isUserProviderReadOnly() {
return provider.isReadOnly();
}
public String exportDirectory() {
return exportDirectory;
}
public boolean exportUsersToFile(String file) throws IOException {
if (!file.endsWith(".xml")) {
file += ".xml";
}
String exportFilePath = exportDirectory + file;
public byte[] exportUsersToFile() throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
XMLWriter writer = null;
try {
writer = new XMLWriter(new FileWriter(exportFilePath), OutputFormat.createPrettyPrint());
writer.write(exportUsers());
} catch (IOException ioe) {
Log.error(ioe);
throw ioe;
} finally {
if (writer != null) {
writer.close();
}
}
XMLWriter writer = writer = new XMLWriter(out, OutputFormat.createPrettyPrint());
writer.write(exportUsers());
return true;
return out.toByteArray();
}
public String exportUsersToString() throws IOException {
StringWriter stringWriter = new StringWriter();
XMLWriter writer = null;
StringWriter stringWriter = new StringWriter();
XMLWriter writer = null;
try {
writer = new XMLWriter(stringWriter, OutputFormat.createPrettyPrint());
writer.write(exportUsers());
} catch (IOException ioe) {
Log.error(ioe);
throw ioe;
Log.error(ioe);
throw ioe;
} finally {
if (writer != null) {
writer.close();
}
if (writer != null) {
writer.close();
}
}
return stringWriter.toString();
}
public boolean validateImportFile(String file) {
String importFilePath = exportDirectory + file;
try {
return new UserSchemaValidator(importFilePath, "messenger-user-schema.xsd.xml").validate();
}
catch (Exception e) {
Log.error(e);
return false;
}
}
public List importUserData(String file) throws MalformedURLException, DocumentException {
String importFilePath = exportDirectory + File.separator + file;
public List<String> importUserData(FileItem file, String previousDomain) throws IOException, DocumentException {
SAXReader reader = new SAXReader();
Document document = reader.read(new File(importFilePath).toURL());
return importUsers(document);
Document document = reader.read(file.getInputStream());
return importUsers(document, previousDomain);
}
private Document exportUsers() {
private Document exportUsers() {
Document document = DocumentHelper.createDocument();
Element root = document.addElement("JiveMessenger");
Collection<User> users = userManager.getUsers();
for (User user : users) {
Element userElement = root.addElement("User");
for (User user : users) {
Element userElement = root.addElement("User");
String userName = user.getUsername();
// if (userName != null) {
// try {
// userName = URLEncoder.encode(userName, "UTF-8");
// } catch (UnsupportedEncodingException e) {
// Log.error(e);
// userName = "";
// }
// } else {
// userName = "";
// }
userElement.addElement("Username").addText(userName);
try {
try {
userElement.addElement("Password").addText(provider.getPassword(user.getUsername()));
}
catch (UserNotFoundException e) {
......@@ -183,51 +119,41 @@ public class ImportExportPlugin implements Plugin {
Log.info("User not found: " + userName + ", setting password to their username");
userElement.addElement("Password").addText(userName);
}
userElement.addElement("Email").addText(user.getEmail() == null ? "" : user.getEmail());
userElement.addElement("Email").addText(user.getEmail() == null ? "" : user.getEmail());
String name = user.getName();
// if (name != null) {
// try {
// name = URLEncoder.encode(name, "UTF-8");
// } catch (UnsupportedEncodingException e) {
// Log.error(e);
// name = "";
// }
// } else {
// name = "";
// }
userElement.addElement("Name").addText(name == null ? "" : name);
String name = user.getName();
userElement.addElement("Name").addText(name == null ? "" : name);
//creation and modified datte are not used as part of the import process but are exported
//for historical purposes, should they be formatted differently?
userElement.addElement("CreationDate").addText(String.valueOf(user.getCreationDate().getTime()));
userElement.addElement("ModifiedDate").addText(String.valueOf(user.getModificationDate().getTime()));
userElement.addElement("CreationDate").addText(String.valueOf(user.getCreationDate().getTime()));
userElement.addElement("ModifiedDate").addText(String.valueOf(user.getModificationDate().getTime()));
Element rosterElement = userElement.addElement("Roster");
Collection<RosterItem> roster = user.getRoster().getRosterItems();
for (RosterItem ri : roster) {
Element itemElement = rosterElement.addElement("Item");
itemElement.addAttribute("jid", ri.getJid().toBareJID());
itemElement.addAttribute("askstatus", String.valueOf(ri.getAskStatus().getValue()));
itemElement.addAttribute("recvstatus", String.valueOf(ri.getRecvStatus().getValue()));
itemElement.addAttribute("substatus", String.valueOf(ri.getSubStatus().getValue()));
itemElement.addAttribute("name", ri.getNickname());
Element rosterElement = userElement.addElement("Roster");
Collection<RosterItem> roster = user.getRoster().getRosterItems();
for (RosterItem ri : roster) {
Element itemElement = rosterElement.addElement("Item");
itemElement.addAttribute("jid", ri.getJid().toBareJID());
itemElement.addAttribute("askstatus", String.valueOf(ri.getAskStatus().getValue()));
itemElement.addAttribute("recvstatus", String.valueOf(ri.getRecvStatus().getValue()));
itemElement.addAttribute("substatus", String.valueOf(ri.getSubStatus().getValue()));
itemElement.addAttribute("name", ri.getNickname());
Element groupElement = itemElement.addElement("Group");
List<String> groups = ri.getGroups();
for (String group : groups) {
groupElement.addText(group);
}
}
}
Element groupElement = itemElement.addElement("Group");
List<String> groups = ri.getGroups();
for (String group : groups) {
groupElement.addText(group);
}
}
}
return document;
}
public List<String> importUsers(Document document) throws DocumentException {
private List<String> importUsers(Document document, String previousDomain) throws DocumentException {
List<String> duplicateUsers = new ArrayList<String>();
UserManager userManager = UserManager.getInstance();
UserManager userManager = UserManager.getInstance();
RosterItemProvider rosterItemProvider = RosterItemProvider.getInstance();
Map<String, List> rosterMap = new HashMap<String, List>();
......@@ -239,19 +165,19 @@ public class ImportExportPlugin implements Plugin {
Element user = (Element) usersIter.next();
String userName = null;
String password = null;
String email = null;
String name = null;
String password = null;
String email = null;
String name = null;
List<RosterItem> rosterItems = new ArrayList<RosterItem>();
Iterator userElements = user.elementIterator();
while (userElements.hasNext()) {
Element userElement = (Element) userElements.next();
Element userElement = (Element) userElements.next();
String nameElement = userElement.getName();
String nameElement = userElement.getName();
if ("Username".equals(nameElement)) {
userName = userElement.getText();
if ("Username".equals(nameElement)) {
userName = userElement.getText();
}
else if ("Password".equals(nameElement)) {
password = userElement.getText();
......@@ -260,7 +186,7 @@ public class ImportExportPlugin implements Plugin {
name = userElement.getText();
}
else if ("Email".equals(nameElement)) {
email = userElement.getText();
email = userElement.getText();
}
else if ("Roster".equals(nameElement)) {
Iterator rosterIter = userElement.elementIterator("Item");
......@@ -281,6 +207,11 @@ public class ImportExportPlugin implements Plugin {
groups.add(group.getText());
}
//used for migration
if (previousDomain != null) {
jid = jid.replace(previousDomain, serverName);
}
rosterItems.add(new RosterItem(new JID(jid),
RosterItem.SubType.getTypeFromInt(Integer.parseInt(substatus)),
RosterItem.AskType.getTypeFromInt(Integer.parseInt(askstatus)),
......@@ -292,14 +223,14 @@ public class ImportExportPlugin implements Plugin {
}
if ((userName != null) && (password != null)) {
try {
userManager.createUser(userName, password, name, email);
try {
userManager.createUser(userName, password, name, email);
rosterMap.put(userName, rosterItems);
}
}
catch (UserAlreadyExistsException e) {
Log.info("User already exists: " + userName);
duplicateUsers.add(userName);
}
}
}
}
......@@ -329,7 +260,7 @@ public class ImportExportPlugin implements Plugin {
}
return duplicateUsers;
}
}
private static String removeDoman(JID jid) {
StringTokenizer tokens = new StringTokenizer(jid.toBareJID(), "@");
......@@ -340,4 +271,3 @@ public class ImportExportPlugin implements Plugin {
return null;
}
}
package org.jivesoftware.messenger.plugin;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import javax.xml.parsers.SAXParserFactory;
import com.sun.msv.reader.util.GrammarLoader;
import com.sun.msv.reader.util.IgnoreController;
import com.sun.msv.verifier.DocumentDeclaration;
import com.sun.msv.verifier.Verifier;
import org.dom4j.Document;
import org.dom4j.DocumentException;
......@@ -16,10 +15,11 @@ import org.xml.sax.ErrorHandler;
import org.xml.sax.Locator;
import org.xml.sax.SAXParseException;
import com.sun.msv.reader.util.GrammarLoader;
import com.sun.msv.reader.util.IgnoreController;
import com.sun.msv.verifier.DocumentDeclaration;
import com.sun.msv.verifier.Verifier;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import javax.xml.parsers.SAXParserFactory;
public class UserSchemaValidator {
private Document doc;
......
<%@ page import="java.io.IOException,
java.util.*,
org.jivesoftware.admin.AdminPageBean,
org.jivesoftware.messenger.plugin.ImportExportPlugin,
org.jivesoftware.messenger.XMPPServer,
org.jivesoftware.util.ParamUtils"
java.util.*,
org.jivesoftware.admin.AdminPageBean,
org.jivesoftware.messenger.plugin.ImportExportPlugin,
org.jivesoftware.messenger.XMPPServer,
org.jivesoftware.util.ParamUtils"
%>
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>
......@@ -11,7 +11,7 @@
<jsp:useBean id="admin" class="org.jivesoftware.util.WebManager" />
<%
admin.init(request, response, session, application, out);
admin.init(request, response, session, application, out);
boolean exportUsers = request.getParameter("exportUsers") != null;
boolean success = request.getParameter("success") != null;
......@@ -21,41 +21,28 @@
String exportText = "";
Map errors = new HashMap();
Map<String, String> errors = new HashMap<String, String>();
if (exportUsers) {
if (exportToFile) {
String file = ParamUtils.getParameter(request, "exportFile");
if ((file == null) || (file.length() <= 0)) {
errors.put("missingFile","missingFile");
}
else {
try {
//todo this could take some, redirect to a progress page?
if (plugin.exportUsersToFile(file)) {
response.sendRedirect("export-user-data.jsp?success=true");
return;
}
else {
errors.put("fileNotCreated","fileNotCreated");
}
}
catch (IOException e) {
errors.put("IOException","IOException");
}
}
String file = ParamUtils.getParameter(request, "exportFile");
if ((file == null) || (file.length() <= 0)) {
errors.put("missingFile","missingFile");
}
else {
response.sendRedirect("export-file.jsp?fileName="+file);
}
}
else {
try {
exportText = plugin.exportUsersToString();
exportText = plugin.exportUsersToString();
}
catch (IOException e) {
errors.put("IOException","IOException");
}
catch (IOException e) {
errors.put("IOException","IOException");
}
}
}
%>
<jsp:useBean id="pageinfo" scope="request" class="org.jivesoftware.admin.AdminPageBean" />
<% // Title of this page and breadcrumbs
String title = "Export User Data";
......@@ -73,14 +60,14 @@
<table cellpadding="0" cellspacing="0" border="0">
<tbody>
<tr>
<td class="jive-icon"><img src="images/error-16x16.gif" width="16" height="16" border="0"></td>
<td class="jive-icon-label">
<% if (errors.containsKey("missingFile")) { %>
Missing or bad file name.
<% } else if (errors.containsKey("IOException") || errors.containsKey("fileNotCreated")) { %>
Couldn't create export file.
<% } %>
</td>
<td class="jive-icon"><img src="images/error-16x16.gif" width="16" height="16" border="0"></td>
<td class="jive-icon-label">
<% if (errors.containsKey("missingFile")) { %>
Missing or bad file name.
<% } else if (errors.containsKey("IOException") || errors.containsKey("fileNotCreated")) { %>
Couldn't create export file.
<% } %>
</td>
</tr>
</tbody>
</table>
......@@ -93,8 +80,8 @@
<table cellpadding="0" cellspacing="0" border="0">
<tbody>
<tr>
<td class="jive-icon"><img src="images/success-16x16.gif" width="16" height="16" border="0"></td>
<td class="jive-icon-label">User data successfully exported.</td>
<td class="jive-icon"><img src="images/success-16x16.gif" width="16" height="16" border="0"></td>
<td class="jive-icon-label">User data successfully exported.</td>
</tr>
</tbody>
</table>
......@@ -107,49 +94,37 @@
<fieldset>
<legend>Export Options</legend>
<div>
<div>
<p>
Select the radio button next to the desired export option and then click on the Export button.
</p>
<table cellpadding="3" cellspacing="0" border="0" width="100%">
<table cellpadding="3" cellspacing="0" border="0" width="100%">
<tbody>
<tr>
<td width="1%">
<input type="radio" name="exporttofile" value="true" <%= exportToFile ? "checked" : "" %> id="rb01">
</td>
<td width="99%">
<label for="rb01"><b>To File</b></label> - Save user data to the specified file location.
</td>
<tr>
<td width="1%">&nbsp;</td>
<td width="99%">
<%= plugin.exportDirectory() %>
</td>
</tr>
<tr>
<td width="1%">&nbsp;</td>
<td width="99%">Export File Name:&nbsp;<input type="text" size="30" maxlength="150" name="exportFile"></td>
</tr>
<td width="1%"><input type="radio" name="exporttofile" value="true" <%= exportToFile ? "checked" : "" %> id="rb01"></td>
<td width="99%"><label for="rb01"><b>To File</b></label> - Save user data to the specified file location.</td>
</tr>
<tr>
<td width="1%">
<input type="radio" name="exporttofile" value="false" <%= !exportToFile ? "checked" : "" %> id="rb02">
</td>
<td width="99%">
<label for="rb02"><b>To Screen</b></label> - Display user data in the text area below.
</td>
<td width="1%">&nbsp;</td>
<td width="99%">Export File Name:&nbsp;<input type="text" size="30" maxlength="150" name="exportFile"></td>
</tr>
<tr>
<td width="1%"><input type="radio" name="exporttofile" value="false" <%= !exportToFile ? "checked" : "" %> id="rb02"></td>
<td width="99%"><label for="rb02"><b>To Screen</b></label> - Display user data in the text area below.</td>
</tr>
<tr>
<td width="1%">&nbsp;</td>
<td width="99%">
<textarea cols="80" rows="20" wrap=off><%=exportText %></textarea>
</td>
<td width="1%">&nbsp;</td>
<td width="99%"><textarea cols="80" rows="20" wrap=off><%=exportText %></textarea></td>
</tr>
</tbody>
</table>
</div>
</div>
</fieldset>
<br><br>
<input type="submit" value="Export">
</form>
<jsp:include page="bottom.jsp" flush="true" />
\ No newline at end of file
<jsp:include page="bottom.jsp" flush="true" />
<%@ page import="org.jivesoftware.admin.AdminPageBean,
org.jivesoftware.messenger.plugin.ImportExportPlugin,
org.jivesoftware.messenger.XMPPServer"
org.jivesoftware.messenger.plugin.ImportExportPlugin,
org.jivesoftware.messenger.XMPPServer"
%>
<jsp:useBean id="pageinfo" scope="request" class="org.jivesoftware.admin.AdminPageBean" />
......@@ -20,7 +20,7 @@
<% if (plugin.isUserProviderReadOnly()) { %>
Sorry, because you are using LDAP as your user store this plugin will not work with your Messenger installation.
Sorry, because you are using LDAP as your user store, this plugin will not work with your Messenger installation.
<% } else { %>
......@@ -28,10 +28,10 @@ The import and export functions allow you to read data into and write user
data from your Jive Messenger installation.
<ul>
<li><a href="import-user-data.jsp">Import User Data</a></li>
<li><a href="import-user-data.jsp">Import User Data</a></li>
<li><a href="export-user-data.jsp">Export User Data</a></li>
</ul>
<% } %>
<jsp:include page="bottom.jsp" flush="true" />
\ No newline at end of file
<jsp:include page="bottom.jsp" flush="true" />
<%@ page import="java.io.IOException,
java.net.MalformedURLException,
java.util.*,
org.dom4j.DocumentException,
org.jivesoftware.admin.AdminPageBean,
org.jivesoftware.messenger.plugin.ImportExportPlugin,
org.jivesoftware.messenger.XMPPServer,
org.jivesoftware.util.ParamUtils"
<%@ page import="java.net.MalformedURLException,
java.util.*,
org.dom4j.DocumentException,
org.apache.commons.fileupload.DiskFileUpload,
org.apache.commons.fileupload.FileItem,
org.jivesoftware.admin.AdminPageBean,
org.jivesoftware.messenger.plugin.ImportExportPlugin,
org.jivesoftware.util.ParamUtils"
%>
<jsp:useBean id="admin" class="org.jivesoftware.util.WebManager" />
<c:set var="admin" value="${admin.manager}" />
<% admin.init(request, response, session, application, out);
<jsp:useBean id="admin" class="org.jivesoftware.util.WebManager" />
<%
admin.init(request, response, session, application, out);
boolean importUsers = request.getParameter("importUsers") != null;
boolean success = request.getParameter("success") != null;
ImportExportPlugin plugin = (ImportExportPlugin) XMPPServer.getInstance().getPluginManager().getPlugin("userimportexport");
List duplicateUsers = new ArrayList();
Map errors = new HashMap();
ImportExportPlugin plugin = (ImportExportPlugin) admin.getXMPPServer().getPluginManager().getPlugin("userimportexport");
List<String> duplicateUsers = new ArrayList<String>();
Map<String, String> errors = new HashMap<String, String>();
if (importUsers) {
String file = ParamUtils.getParameter(request, "importFile");
if ((file == null) || (file.length() <= 0)) {
errors.put("badFile", "badFile");
DiskFileUpload dfu = new DiskFileUpload();
List fileItems = dfu.parseRequest(request);
Iterator i = fileItems.iterator();
FileItem fi = (FileItem) i.next();
FileItem pd = (FileItem) i.next();
String previousDomain = pd.getString();
try {
if (isEmpty(previousDomain)) {
duplicateUsers.addAll(plugin.importUserData(fi, null));
}
else if (!isEmpty(previousDomain)) {
duplicateUsers.addAll(plugin.importUserData(fi, previousDomain));
}
else {
errors.put("missingDomain", "missingDomain");
}
if (duplicateUsers.size() == 0) {
response.sendRedirect("import-user-data.jsp?success=true");
return;
}
errors.put("userAlreadyExists", "userAlreadyExists");
}
catch (MalformedURLException e) {
errors.put("IOException", "IOException");
}
else {
try {
//todo this could take some, redirect to a progress page?
if (plugin.validateImportFile(file)) {
duplicateUsers.addAll(plugin.importUserData(file));
if (duplicateUsers.size() == 0) {
response.sendRedirect("import-user-data.jsp?success=true");
return;
}
errors.put("userAlreadyExists", "userAlreadyExists");
}
else {
errors.put("invalidUserFile", "invalidUserFile");
}
}
catch (MalformedURLException e) {
errors.put("MalformedURLException", "MalformedURLException");
}
catch (DocumentException e) {
errors.put("DocumentException", "DocumentException");
}
}
}
catch (DocumentException e) {
errors.put("DocumentException", "DocumentException");
}
}
%>
<jsp:useBean id="pageinfo" scope="request" class="org.jivesoftware.admin.AdminPageBean" />
......@@ -64,35 +68,37 @@
<% if (errors.size() > 0) { %>
<div class="jive-error">
<div class="jive-error">
<table cellpadding="0" cellspacing="0" border="0">
<tbody>
<tr>
<td class="jive-icon"><img src="images/error-16x16.gif" width="16" height="16" border="0"></td>
<td class="jive-icon-label">
<% if (errors.containsKey("MalformedURLException") || errors.containsKey("badFile")) { %>
Missing or bad file name.
<% } else if (errors.containsKey("DocumentException")) { %>
Import failed.
<% } else if (errors.containsKey("invalidUserFile")) { %>
The import file does not match the user schema.
<% } else if (errors.containsKey("userAlreadyExists")) { %>
The following users are already exist in the system and were not loaded:<br>
<%
Iterator iter = duplicateUsers.iterator();
while (iter.hasNext()) {
String username = (String) iter.next();
%><%= username %><%
if (iter.hasNext()) {
%>,&nbsp;<%
} else {
%>.<%
}
}
} %>
</td>
<tbody>
<tr>
<td class="jive-icon"><img src="images/error-16x16.gif" width="16" height="16" border="0"></td>
<td class="jive-icon-label">
<% if (errors.containsKey("missingDomain")) { %>
You must supply both a existing and new domain name.
<% } else if (errors.containsKey("IOException")) { %>
Missing or bad file name.
<% } else if (errors.containsKey("DocumentException")) { %>
Import failed.
<% } else if (errors.containsKey("invalidUserFile")) { %>
The import file does not match the user schema.
<% } else if (errors.containsKey("userAlreadyExists")) { %>
The following users are already exist in the system and were not loaded:<br>
<%
Iterator iter = duplicateUsers.iterator();
while (iter.hasNext()) {
String username = (String) iter.next();
%><%= username %><%
if (iter.hasNext()) {
%>,&nbsp;<%
} else {
%>.<%
}
}
} %>
</td>
</tr>
</tbody>
</tbody>
</table>
</div>
<br>
......@@ -101,46 +107,53 @@
<div class="jive-success">
<table cellpadding="0" cellspacing="0" border="0">
<tbody>
<tbody>
<tr>
<td class="jive-icon"><img src="images/success-16x16.gif" width="16" height="16" border="0"></td>
<td class="jive-icon-label">All users added successfully.</td>
<td class="jive-icon"><img src="images/success-16x16.gif" width="16" height="16" border="0"></td>
<td class="jive-icon-label">All users added successfully.</td>
</tr>
</tbody>
</tbody>
</table>
</div>
<br>
<% } %>
<form action="import-user-data.jsp?importUsers" method="post" enctype="multipart/form-data">
<form action="import-user-data.jsp?importUsers" method="post">
<div class="jive-table">
<table cellpadding="0" cellspacing="0" border="0" width="100%">
<thead>
<tr>
<th>Import Properties</th>
</tr>
</thead>
<tr class="jive-even">
<td style="border-right:1px #ccc solid;">Import Location:</td>
</tr>
<tr class="jive-odd">
<td style="border-right:1px #ccc solid;"><%= plugin.exportDirectory() %></td>
</tr>
<tr class="jive-even">
<td style="border-right:1px #ccc solid;">Import File Name:</td>
</tr>
<tr class="jive-odd">
<td style="border-right:1px #ccc solid;"><input type="text" size="30" maxlength="150" name="importFile"></td>
</tr>
</table>
</div>
<br><br>
<fieldset>
<legend>Import</legend>
<div>
<p>
Use the Browse button to select the file that conatians the Jive Messenger user data to be imported, then click on the Import button.
</p>
<input type="file" name="thefile"><input type="submit" value="Import">
<br><br><br>
<p>
<b>Optional</b> - Use the field below to replace the domain name of user roster entries with the current hostname.
See the migration section of the <a href="../../plugin-admin.jsp?plugin=userimportexport&showReadme=true">readme</a> for details.
</p>
Existing Domain:<input type="text" size="20" maxlength="150" name="previousDomain" value=""/>
</div>
</fieldset>
<input type="submit" value="Import">
</form>
<jsp:include page="bottom.jsp" flush="true" />
\ No newline at end of file
<jsp:include page="bottom.jsp" flush="true" />
<%!
public boolean isEmpty(String s) {
if (s == null) {
return true;
}
if (s.trim().length() == 0) {
return true;
}
return false;
}
%>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment