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,23 +2,27 @@
<html>
<head>
<title>User Import/Export Plugin Changelog</title>
<style type="text/css">
<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;
......@@ -32,11 +36,12 @@
font-weight : bold;
color : #060;
}
PRE {
font-family : courier new;
font-size : 100%;
}
</style>
</style>
</head>
<body>
......@@ -44,6 +49,13 @@
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>
......
......@@ -6,9 +6,9 @@
<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>
<version>2.0</version>
<date>09/01/2005</date>
<minServerVersion>2.1.5</minServerVersion>
<adminconsole>
<tab id="tab-users">
......
This diff is collapsed.
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"),
......@@ -48,33 +47,12 @@ public class ImportExportPlugin implements Plugin {
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,37 +62,19 @@ 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());
XMLWriter writer = writer = new XMLWriter(out, OutputFormat.createPrettyPrint());
writer.write(exportUsers());
} catch (IOException ioe) {
Log.error(ioe);
throw ioe;
} finally {
if (writer != null) {
writer.close();
}
}
return true;
return out.toByteArray();
}
public String exportUsersToString() throws IOException {
......@@ -135,24 +95,10 @@ public class ImportExportPlugin implements Plugin {
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() {
......@@ -163,16 +109,6 @@ public class ImportExportPlugin implements Plugin {
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 {
......@@ -186,16 +122,6 @@ public class ImportExportPlugin implements Plugin {
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);
//creation and modified datte are not used as part of the import process but are exported
......@@ -224,7 +150,7 @@ public class ImportExportPlugin implements Plugin {
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();
......@@ -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)),
......@@ -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;
......
......@@ -21,7 +21,7 @@
String exportText = "";
Map errors = new HashMap();
Map<String, String> errors = new HashMap<String, String>();
if (exportUsers) {
if (exportToFile) {
String file = ParamUtils.getParameter(request, "exportFile");
......@@ -29,19 +29,7 @@
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");
}
response.sendRedirect("export-file.jsp?fileName="+file);
}
}
else {
......@@ -55,7 +43,6 @@
}
%>
<jsp:useBean id="pageinfo" scope="request" class="org.jivesoftware.admin.AdminPageBean" />
<% // Title of this page and breadcrumbs
String title = "Export User Data";
......@@ -108,45 +95,33 @@
<fieldset>
<legend>Export Options</legend>
<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%">
<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>
<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%">&nbsp;</td>
<td width="99%">Export File Name:&nbsp;<input type="text" size="30" maxlength="150" name="exportFile"></td>
</tr>
</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%"><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="99%"><textarea cols="80" rows="20" wrap=off><%=exportText %></textarea></td>
</tr>
</tbody>
</table>
</div>
</fieldset>
<br><br>
<input type="submit" value="Export">
......
......@@ -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 { %>
......
<%@ page import="java.io.IOException,
java.net.MalformedURLException,
<%@ 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.messenger.XMPPServer,
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);
<%
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();
ImportExportPlugin plugin = (ImportExportPlugin) admin.getXMPPServer().getPluginManager().getPlugin("userimportexport");
List<String> duplicateUsers = new ArrayList<String>();
Map errors = new HashMap();
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 {
try {
//todo this could take some, redirect to a progress page?
if (plugin.validateImportFile(file)) {
duplicateUsers.addAll(plugin.importUserData(file));
errors.put("missingDomain", "missingDomain");
}
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");
errors.put("IOException", "IOException");
}
catch (DocumentException e) {
errors.put("DocumentException", "DocumentException");
}
}
}
%>
<jsp:useBean id="pageinfo" scope="request" class="org.jivesoftware.admin.AdminPageBean" />
......@@ -70,7 +74,9 @@
<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")) { %>
<% 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.
......@@ -113,34 +119,41 @@
<% } %>
<form action="import-user-data.jsp?importUsers" method="post" enctype="multipart/form-data">
<form action="import-user-data.jsp?importUsers" method="post">
<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">
<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><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=""/>
<br><br>
</div>
</fieldset>
<input type="submit" value="Import">
</form>
<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