ImportExportUtilities.java
/*
* This software was designed and created by Jason Carroll.
* Copyright (c) 2002, 2003, 2004 Jason Carroll.
* The author can be reached at jcarroll@cowsultants.com
* ITracker website: http://www.cowsultants.com
* ITracker forums: http://www.cowsultants.com/phpBB/index.php
*
* This program is free software; you can redistribute it and/or modify
* it only under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* 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 General Public License for more details.
*/
package org.itracker.web.util;
import org.apache.commons.lang.StringUtils;
import org.dom4j.DocumentFactory;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
import org.itracker.ImportExportException;
import org.itracker.core.resources.ITrackerResources;
import org.itracker.model.*;
import org.itracker.model.util.CustomFieldUtilities;
import org.itracker.model.util.ProjectUtilities;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import java.io.*;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
/**
* FIXME: This is not XML, this is string concatenating/parsing. Use proper SAX Handler or remove this unsave code. see java.xml.parsers for more information.
* <p/>
* This class provides functionality needed to import and export issues and their associated
* data as XML. This xml provides all the data necessary to import the issues into another
* instance of ITracker or some other issue tracking tool.
*/
public class ImportExportUtilities implements ImportExportTags {
private static final Logger logger = LoggerFactory.getLogger(ImportExportUtilities.class);
public static final int IMPORT_STAT_NEW = 0;
public static final int IMPORT_STAT_REUSED = 1;
public static final int IMPORT_STAT_USERS = 0;
public static final int IMPORT_STAT_PROJECTS = 1;
public static final int IMPORT_STAT_ISSUES = 2;
public static final int IMPORT_STAT_STATUSES = 3;
public static final int IMPORT_STAT_SEVERITIES = 4;
public static final int IMPORT_STAT_RESOLUTIONS = 5;
public static final int IMPORT_STAT_FIELDS = 6;
public ImportExportUtilities() {
}
private static DocumentFactory getDocumentFactory() {
return DocumentFactory.getInstance();
}
/**
* Takes an XML file matching the ITracker import/export DTD and returns an array
* of AbstractBean objects. The array will contain all of the projects, components
* versions, users, custom fields, and issues contained in the XML.
*
* @param xmlReader an xml reader to import
* @throws ImportExportException thrown if the xml can not be parsed into the appropriate objects
*/
public static AbstractEntity[] importIssues(Reader xmlReader) throws ImportExportException {
AbstractEntity[] abstractBeans;
try {
logger.debug("Starting XML data import.");
XMLReader reader = XMLReaderFactory.createXMLReader();
ImportHandler handler = new ImportHandler();
reader.setContentHandler(handler);
reader.setErrorHandler(handler);
reader.parse(new InputSource(xmlReader));
abstractBeans = handler.getModels();
logger.debug("Imported a total of " + abstractBeans.length + " beans.");
} catch (Exception e) {
logger.error("Exception.", e);
throw new ImportExportException(e.getMessage());
}
return abstractBeans;
}
/**
* export the issues to an XML and write it to the response.
* @param issues
* @param config
* @param request
* @param response
* @return if <code>true</code> the export was sucessful.
* @throws ServletException
* @throws IOException
*/
public static boolean exportIssues(List<Issue> issues, SystemConfiguration config, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/xml; charset=UTF-8");
response.setHeader("Content-Disposition", "attachment; filename=\"issue_export.xml\"");
XMLWriter writer = new XMLWriter(response.getOutputStream(), OutputFormat.createCompactFormat());
try {
// TODO instead to have a string returned, it should directly serialize the
// export to the response-writer.
ImportExportUtilities.exportIssues(writer, issues, config);
} catch (ImportExportException iee) {
logger.error("Error exporting issue data. Message: " + iee.getMessage(), iee);
return false;
} finally {
if (null != writer) {
writer.flush();
writer.close();
}
}
return true;
}
public static AbstractEntity importXml(InputSource is) throws Exception {
// TODO unmarshal from is
JAXBContext jc = JAXBContext.newInstance("org.itracker");
Unmarshaller u = jc.createUnmarshaller();
AbstractEntity o = (AbstractEntity) u.unmarshal(is);
return o;
}
public static void export(AbstractEntity o, OutputStream os) throws Exception {
// TODO marshal to System.out
JAXBContext jc = JAXBContext.newInstance("org.itracker");
Marshaller m = jc.createMarshaller();
m.marshal(o, System.out);
}
public static void exportIssues(XMLWriter writer, List<Issue> issues, SystemConfiguration config) throws ImportExportException {
Element elRoot = getDocumentFactory().createElement(TAG_ROOT);
try {
writer.startDocument();
writer.writeOpen(elRoot);
exportConfigModels(writer, config);
exportIssuesModels(writer, issues);
writer.writeClose(elRoot);
writer.endDocument();
} catch (SAXException e) {
throw new ImportExportException(e.getMessage(), ImportExportException.TYPE_UNKNOWN);
} catch (IOException e) {
throw new ImportExportException("Problem writing export stream. "
+ e.getMessage(), ImportExportException.TYPE_UNKNOWN);
}
}
public static void exportConfigModels(XMLWriter writer, SystemConfiguration config) throws IOException {
if (config != null) {
Element elConfigs = getDocumentFactory().createElement(TAG_CONFIGURATION);
writer.writeOpen(elConfigs);
getConfigurationXML(writer, config);
writer.writeClose(elConfigs);
}
}
public static void exportIssuesModels(XMLWriter writer, List<Issue> issues) throws IOException {
HashMap<String, Project> projects = new HashMap<>();
HashMap<String, User> users = new HashMap<>();
if (issues == null || issues.size() == 0) {
throw new IllegalArgumentException("The issue list was null or zero length.");
}
// initialize dataset
for (Issue issue : issues) {
if (!projects.containsKey(issue.getProject().getId().toString())) {
if (logger.isDebugEnabled())
logger.debug("Adding new project " + issue.getProject().getId() + " to export.");
projects.put(issue.getProject().getId().toString(), issue.getProject());
}
if (issue.getCreator() != null && !users.containsKey(issue.getCreator().getId().toString())) {
if (logger.isDebugEnabled())
logger.debug("Adding new user " + issue.getCreator().getId() + " to export.");
users.put(issue.getCreator().getId().toString(), issue.getCreator());
}
if (issue.getOwner() != null && !users.containsKey(issue.getOwner().getId().toString())) {
if (logger.isDebugEnabled())
logger.debug("Adding new user " + issue.getOwner().getId() + " to export.");
users.put(issue.getOwner().getId().toString(), issue.getOwner());
}
List<IssueHistory> history = issue.getHistory();
for (IssueHistory aHistory : history) {
if (aHistory != null && aHistory.getUser() != null && !users.containsKey(aHistory.getUser().getId().toString())) {
if (logger.isDebugEnabled())
logger.debug("Adding new user " + aHistory.getUser().getId() + " to export.");
users.put(aHistory.getUser().getId().toString(), aHistory.getUser());
}
}
List<IssueAttachment> attachments = issue.getAttachments();
for (IssueAttachment attachment : attachments) {
if (attachment != null && attachment.getUser() != null && !users.containsKey(attachment.getUser().getId().toString())) {
if (logger.isDebugEnabled())
logger.debug("Adding new user " + attachment.getUser().getId() + " to export.");
users.put(attachment.getUser().getId().toString(), attachment.getUser());
}
}
}
for (String s : projects.keySet()) {
Project project = projects.get(s);
for (User o:project.getOwners()) {
users.put(o.getId().toString(), o);
}
}
Element elUsers = getDocumentFactory().createElement(TAG_USERS);
writer.writeOpen(elUsers);
for (User u: users.values()) {
exportModel(writer, u);
}
writer.writeClose(elUsers);
Element elProjects = getDocumentFactory().createElement(TAG_PROJECTS);
writer.writeOpen(elProjects);
for (Project s : projects.values()) {
exportModel(writer, s);
}
writer.writeClose(elProjects);
Element elIssues = getDocumentFactory().createElement(TAG_ISSUES);
writer.writeOpen(elIssues);
for (Issue issue: issues) {
exportModel(writer, issue);
}
writer.writeClose(elIssues);
}
/**
* Takes an array of IssueModels and exports them as XML suitable for import into another
* instance of ITracker, or another issue tracking tool.
*
* @param issues an array of Issue objects to export
* @throws ImportExportException thrown if the array of issues can not be exported
*/
public static String exportIssues(List<Issue> issues, SystemConfiguration config) throws ImportExportException {
StringBuffer buf = new StringBuffer();
HashMap<String, Project> projects = new HashMap<String, Project>();
HashMap<String, User> users = new HashMap<String, User>();
if (issues == null || issues.size() == 0) {
throw new ImportExportException("The issue list was null or zero length.");
}
buf.append("<" + TAG_ISSUES + ">\n");
for (int i = 0; i < issues.size(); i++) {
if (!projects.containsKey(issues.get(i).getProject().getId().toString())) {
logger.debug("Adding new project " + issues.get(i).getProject().getId() + " to export.");
projects.put(issues.get(i).getProject().getId().toString(), issues.get(i).getProject());
}
if (issues.get(i).getCreator() != null && !users.containsKey(issues.get(i).getCreator().getId().toString())) {
logger.debug("Adding new user " + issues.get(i).getCreator().getId() + " to export.");
users.put(issues.get(i).getCreator().getId().toString(), issues.get(i).getCreator());
}
if (issues.get(i).getOwner() != null && !users.containsKey(issues.get(i).getOwner().getId().toString())) {
logger.debug("Adding new user " + issues.get(i).getOwner().getId() + " to export.");
users.put(issues.get(i).getOwner().getId().toString(), issues.get(i).getOwner());
}
List<IssueHistory> history = issues.get(i).getHistory();
for (int j = 0; j < history.size(); j++) {
if (history.get(j) != null && history.get(j).getUser() != null && !users.containsKey(history.get(j).getUser().getId().toString())) {
logger.debug("Adding new user " + history.get(j).getUser().getId() + " to export.");
users.put(history.get(j).getUser().getId().toString(), history.get(j).getUser());
}
}
List<IssueAttachment> attachments = issues.get(i).getAttachments();
for (int j = 0; j < attachments.size(); j++) {
if (attachments.get(j) != null && attachments.get(j).getUser() != null && !users.containsKey(attachments.get(j).getUser().getId().toString())) {
logger.debug("Adding new user " + attachments.get(j).getUser().getId() + " to export.");
users.put(attachments.get(j).getUser().getId().toString(), attachments.get(j).getUser());
}
}
buf.append(exportModel((AbstractEntity) issues.get(i)));
}
buf.append("</" + TAG_ISSUES + ">\n");
buf.append("</" + TAG_ROOT + ">\n");
buf.insert(0, "</" + TAG_PROJECTS + ">\n");
for (Iterator<String> iter = projects.keySet().iterator(); iter.hasNext(); ) {
Project project = (Project) projects.get((String) iter.next());
for (int i = 0; i < project.getOwners().size(); i++) {
users.put(project.getOwners().get(i).getId().toString(), project.getOwners().get(i));
}
buf.insert(0, exportModel((AbstractEntity) project));
}
buf.insert(0, "<" + TAG_PROJECTS + ">\n");
buf.insert(0, "</" + TAG_USERS + ">\n");
for (Iterator<String> iter = users.keySet().iterator(); iter.hasNext(); ) {
buf.insert(0, exportModel((AbstractEntity) users.get((String) iter.next())));
}
buf.insert(0, "<" + TAG_USERS + ">\n");
if (config != null) {
buf.insert(0, "</" + TAG_CONFIGURATION + ">\n");
buf.insert(0, getConfigurationXML(config));
buf.insert(0, "<" + TAG_CONFIGURATION + ">\n");
}
buf.insert(0, "<" + TAG_ROOT + ">\n");
return buf.toString();
}
/**
* Returns the appropriate XML block for a given model.
*
* @param abstractBean a model that extends AbstractEntity
* @throws ImportExportException thrown if the given model can not be exported
*/
public static String exportModel(AbstractEntity abstractBean) throws ImportExportException {
ByteArrayOutputStream os = new ByteArrayOutputStream();
try {
XMLWriter writer = new XMLWriter(os);
exportModel(writer, abstractBean);
writer.close();
return (os.toString("utf-8"));
} catch (Exception e) {
logger.error("could not create xml string", e);
throw new ImportExportException(e.getMessage(), ImportExportException.TYPE_UNKNOWN);
}
}
public static void exportModel(XMLWriter writer, AbstractEntity abstractBean) throws IOException {
if (abstractBean == null) {
throw new IllegalArgumentException("The bean to export was null.");
} else if (abstractBean instanceof Issue) {
getIssueXML(writer, (Issue) abstractBean);
} else if (abstractBean instanceof Project) {
getProjectXML(writer, (Project) abstractBean);
} else if (abstractBean instanceof User) {
getUserXML(writer, (User) abstractBean);
} else {
throw new IllegalArgumentException("This bean type can not be exported.");
}
}
/**
* Write the properties to simple XML tags
* @param writer
* @param tags
* @throws IOException
*/
private static void addPropertyTags(XMLWriter writer, Properties tags) throws IOException {
DocumentFactory factory = getDocumentFactory();
for (String tag: tags.stringPropertyNames()) {
Element el = factory.createElement(tag);
el.setText(tags.getProperty(tag));
writer.write(el);
}
}
/**
* Write the properties to simple CDATA tags
* @param writer
* @param tags
* @throws IOException
*/
private static void addCdataPropertyTags(XMLWriter writer, Properties tags) throws IOException {
DocumentFactory factory = getDocumentFactory();
for (String tag: tags.stringPropertyNames()) {
Element el = factory.createElement(tag);
el.add(factory.createCDATA(tags.getProperty(tag)));
writer.write(el);
}
}
private static void addIdCollection(XMLWriter writer, List<? extends AbstractEntity> entities,
String elName, String itName, String idPrefix) throws IOException {
if (entities.size() > 0) {
Element elTmp;
final DocumentFactory factory = getDocumentFactory();
final Element el = factory.createElement(elName);
writer.writeOpen(el);
for (AbstractEntity c: entities) {
elTmp = factory.createElement(itName);
elTmp.setText(idPrefix + c.getId());
writer.write(elTmp);
}
writer.writeClose(el);
}
}
private static void addIssueFields(XMLWriter writer, List<IssueField> entities) throws IOException {
if (entities.size() > 0) {
Element elTmp;
final DocumentFactory factory = getDocumentFactory();
final Element el = factory.createElement(TAG_ISSUE_FIELDS);
writer.writeOpen(el);
for (IssueField c: entities) {
elTmp = factory.createElement(TAG_ISSUE_FIELD);
elTmp.addAttribute(ATTR_ID, TAG_CUSTOM_FIELD + c.getId());
elTmp.add(factory.createCDATA(c.getValue(EXPORT_LOCALE)));
writer.write(elTmp);
}
writer.writeClose(el);
}
}
private static void addIssueAttachments(XMLWriter writer, List<IssueAttachment> entities) throws IOException {
if (entities.size() > 0) {
Element elTmp;
final DocumentFactory factory = getDocumentFactory();
final Element el = factory.createElement(TAG_ISSUE_ATTACHMENTS);
writer.writeOpen(el);
for (IssueAttachment c: entities) {
elTmp = factory.createElement(TAG_ISSUE_ATTACHMENT);
writer.writeOpen(elTmp);
Properties pTmp = new Properties();
pTmp.setProperty(TAG_ISSUE_ATTACHMENT_DESCRIPTION, ITrackerResources.escapeUnicodeString(c.getDescription(), false));
pTmp.setProperty(TAG_ISSUE_ATTACHMENT_FILENAME, ITrackerResources.escapeUnicodeString(c.getFileName(), false));
pTmp.setProperty(TAG_ISSUE_ATTACHMENT_ORIGFILE, ITrackerResources.escapeUnicodeString(c.getOriginalFileName(), false));
addCdataPropertyTags(writer, pTmp);
pTmp.clear();
pTmp.setProperty(TAG_ISSUE_ATTACHMENT_SIZE, String.valueOf(c.getSize()));
pTmp.setProperty(TAG_ISSUE_ATTACHMENT_TYPE, StringUtils.defaultString(c.getType(), "application/octet-stream"));
pTmp.setProperty(TAG_ISSUE_ATTACHMENT_CREATOR, TAG_USER + c.getUser().getId());
addPropertyTags(writer, pTmp);
writer.writeClose(elTmp);
}
writer.writeClose(el);
}
}
private static void addIssueHistory(XMLWriter writer, List<IssueHistory> entities) throws IOException {
if (entities.size() > 0) {
Element elTmp;
final DocumentFactory factory = getDocumentFactory();
final Element el = factory.createElement(TAG_ISSUE_HISTORY);
writer.writeOpen(el);
for (IssueHistory c: entities) {
elTmp = factory.createElement(TAG_HISTORY_ENTRY);
elTmp.addAttribute(ATTR_CREATOR_ID, TAG_USER + c.getUser().getId());
elTmp.addAttribute(ATTR_DATE, DATE_FORMATTER.format(c.getCreateDate()));
elTmp.addAttribute(ATTR_STATUS, String.valueOf(c.getStatus()));
writer.writeOpen(elTmp);
writer.write(factory.createCDATA(ITrackerResources.escapeUnicodeString(c.getDescription(), false)));
writer.writeClose(elTmp);
}
writer.writeClose(el);
}
}
public static void getIssueXML(XMLWriter writer, Issue issue) throws IOException {
Element elIssue = getDocumentFactory().createElement(TAG_ISSUE);
elIssue.addAttribute(ATTR_ID, TAG_ISSUE+issue.getId());
elIssue.addAttribute(ATTR_SYSTEMID, String.valueOf(issue.getId()));
writer.writeOpen(elIssue);
final Properties tags = new Properties();
final Properties ctags = new Properties();
tags.setProperty(TAG_ISSUE_PROJECT, TAG_PROJECT + issue.getProject().getId());
ctags.setProperty(TAG_ISSUE_DESCRIPTION, ITrackerResources.escapeUnicodeString(issue.getDescription(), false));
tags.setProperty(TAG_ISSUE_SEVERITY, String.valueOf(issue.getSeverity()));
tags.setProperty(TAG_ISSUE_STATUS, String.valueOf(issue.getStatus()));
tags.setProperty(TAG_ISSUE_RESOLUTION, StringUtils.defaultString(issue.getResolution()));
if (issue.getTargetVersion() != null) {
tags.setProperty(TAG_TARGET_VERSION_ID, TAG_VERSION + issue.getTargetVersion().getId());
}
tags.setProperty(TAG_CREATE_DATE, DATE_FORMATTER.format(issue.getCreateDate()));
tags.setProperty(TAG_LAST_MODIFIED, DATE_FORMATTER.format(issue.getLastModifiedDate()));
tags.setProperty(TAG_CREATOR, TAG_USER + issue.getCreator().getId());
if (issue.getOwner() != null) {
tags.setProperty(TAG_OWNER, TAG_USER + issue.getOwner().getId());
}
addPropertyTags(writer, tags);
addCdataPropertyTags(writer, ctags);
addIdCollection(writer, issue.getComponents(), TAG_ISSUE_COMPONENTS, TAG_COMPONENT_ID, TAG_COMPONENT);
addIdCollection(writer, issue.getVersions(), TAG_ISSUE_VERSIONS, TAG_VERSION_ID, TAG_VERSION);
addIssueFields(writer, issue.getFields());
addIssueAttachments(writer, issue.getAttachments());
addIssueHistory(writer, issue.getHistory());
writer.writeClose(elIssue);
}
/**
* Generates an XML block that encapsulates an issue for import or export. This
* function will not generate the XML for other models needed for a complete import
* or export.
*
* @param issue an Issue to generate the XML for
* @return a String containing the XML for the issue
*/
public static String getIssueXML(Issue issue) {
if (issue == null) {
return "";
}
ByteArrayOutputStream os = new ByteArrayOutputStream();
try {
XMLWriter writer = new XMLWriter(os);
getIssueXML(writer, issue);
writer.close();
return (os.toString("utf-8"));
} catch (Exception e) {
logger.error("could not create xml string", e);
return "";
}
}
private static void addProjectComponents(XMLWriter writer, List<Component> entities) throws IOException {
if (entities.size() > 0) {
Element elTmp;
final DocumentFactory factory = getDocumentFactory();
final Element el = factory.createElement(TAG_COMPONENTS);
writer.writeOpen(el);
for (Component c : entities) {
elTmp = factory.createElement(TAG_COMPONENT);
elTmp.addAttribute(ATTR_ID, TAG_CUSTOM_FIELD + c.getId());
elTmp.addAttribute(ATTR_SYSTEMID, String.valueOf(c.getId()));
writer.writeOpen(elTmp);
Properties tags = new Properties();
tags.setProperty(TAG_COMPONENT_NAME, ITrackerResources.escapeUnicodeString(c.getName(), false));
tags.setProperty(TAG_COMPONENT_DESCRIPTION, ITrackerResources.escapeUnicodeString(c.getDescription(), false));
addCdataPropertyTags(writer, tags);
writer.writeClose(elTmp);
}
writer.writeClose(el);
}
}
private static void addProjectVersions(XMLWriter writer, List<Version> entities) throws IOException {
if (entities.size() > 0) {
Element elTmp;
final DocumentFactory factory = getDocumentFactory();
final Element el = factory.createElement(TAG_VERSIONS);
writer.writeOpen(el);
for (Version c : entities) {
elTmp = factory.createElement(TAG_VERSION);
elTmp.addAttribute(ATTR_ID, TAG_VERSION + c.getId());
elTmp.addAttribute(ATTR_SYSTEMID, String.valueOf(c.getId()));
writer.writeOpen(elTmp);
Properties tags = new Properties();
tags.setProperty(TAG_VERSION_NUMBER, ITrackerResources.escapeUnicodeString(c.getNumber(), false));
tags.setProperty(TAG_VERSION_DESCRIPTION, ITrackerResources.escapeUnicodeString(c.getDescription(), false));
addCdataPropertyTags(writer, tags);
writer.writeClose(elTmp);
}
writer.writeClose(el);
}
}
private static void getProjectXML(XMLWriter writer, Project project) throws IOException {
Element elProject = getDocumentFactory().createElement(TAG_PROJECT);
elProject.addAttribute(ATTR_ID, TAG_PROJECT + project.getId());
elProject.addAttribute(ATTR_SYSTEMID, String.valueOf(project.getId()));
writer.writeOpen(elProject);
Properties tags = new Properties();
tags.setProperty(TAG_PROJECT_NAME, ITrackerResources.escapeUnicodeString(project.getName(), false));
tags.setProperty(TAG_PROJECT_DESCRIPTION, ITrackerResources.escapeUnicodeString(project.getDescription(), false));
addCdataPropertyTags(writer, tags);
tags.clear();
tags.setProperty(TAG_PROJECT_STATUS, ProjectUtilities.getStatusName(project.getStatus(), EXPORT_LOCALE));
tags.setProperty(TAG_PROJECT_OPTIONS, String.valueOf(project.getOptions()));
addPropertyTags(writer, tags);
addIdCollection(writer, project.getCustomFields(), TAG_PROJECT_FIELDS, TAG_PROJECT_FIELD_ID, TAG_CUSTOM_FIELD);
addIdCollection(writer, project.getOwners(), TAG_PROJECT_OWNERS, TAG_PROJECT_OWNER_ID, TAG_USER);
addProjectComponents(writer, project.getComponents());
addProjectVersions(writer, project.getVersions());
writer.writeClose(elProject);
}
/**
* Generates an XML block that encapsulates a project for import or export. This
* function will not generate the XML for other models needed for a complete import
* or export.
*
* @param project a Project to generate the XML for
* @return a String containing the XML for the project
*/
public static String getProjectXML(Project project) {
if (project == null) {
return "";
}
ByteArrayOutputStream os = new ByteArrayOutputStream();
try {
XMLWriter writer = new XMLWriter(os);
getProjectXML(writer, project);
writer.close();
return (os.toString("utf-8"));
} catch (Exception e) {
logger.error("could not create xml string", e);
return "";
}
}
public static void getUserXML(XMLWriter writer, User user) throws IOException {
Element elUser = getDocumentFactory().createElement(TAG_USER);
elUser.addAttribute(ATTR_ID, TAG_USER + user.getId());
elUser.addAttribute(ATTR_SYSTEMID, String.valueOf(user.getId()));
writer.writeOpen(elUser);
Properties tags = new Properties();
tags.setProperty(TAG_LOGIN, ITrackerResources.escapeUnicodeString(user.getLogin(), false));
tags.setProperty(TAG_FIRST_NAME, ITrackerResources.escapeUnicodeString(user.getFirstName(), false));
tags.setProperty(TAG_LAST_NAME, ITrackerResources.escapeUnicodeString(user.getLastName(), false));
tags.setProperty(TAG_EMAIL, ITrackerResources.escapeUnicodeString(user.getEmail(), false));
addCdataPropertyTags(writer, tags);
tags.clear();
tags.setProperty(TAG_USER_STATUS, String.valueOf(user.getStatus()));
tags.setProperty(TAG_SUPER_USER, String.valueOf(user.isSuperUser()));
addPropertyTags(writer, tags);
writer.writeClose(elUser);
}
/**
* Generates an XML block that encapsulates a user for import or export. This
* function will not generate the XML for other models needed for a complete import
* or export.
*
* @param user a User to generate the XML for
* @return a String containing the XML for the user
*/
public static String getUserXML(User user) {
if (user == null) {
return "";
}
ByteArrayOutputStream os = new ByteArrayOutputStream();
try {
XMLWriter writer = new XMLWriter(os);
getUserXML(writer, user);
writer.close();
return (os.toString("utf-8"));
} catch (Exception e) {
logger.error("could not create xml string", e);
return "";
}
}
public static void getConfigurationXML(XMLWriter writer, SystemConfiguration config) throws IOException {
Properties tags = new Properties();
tags.setProperty(TAG_CONFIGURATION_VERSION, StringUtils.defaultString(config.getVersion(), "null"));
addCdataPropertyTags(writer, tags);
getCustomFieldsXML(writer, config);
getConfigurationXML(writer, config.getResolutions(), TAG_RESOLUTIONS, TAG_RESOLUTION);
getConfigurationXML(writer, config.getSeverities(), TAG_SEVERITIES, TAG_SEVERITY);
getConfigurationXML(writer, config.getStatuses(), TAG_STATUSES, TAG_STATUS);
}
private static void getConfigurationXML(XMLWriter writer, List<Configuration> cs, String elName, String itName) throws IOException {
Element el = getDocumentFactory().createElement(elName);
writer.writeOpen(el);
for (Configuration c: cs) {
Element elIt = getDocumentFactory().createElement(itName);
elIt.addAttribute(ATTR_VALUE, c.getValue());
elIt.addAttribute(ATTR_ORDER, String.valueOf(c.getOrder()));
writer.writeOpen(elIt);
writer.write(getDocumentFactory().createCDATA(ITrackerResources.escapeUnicodeString(c.getName(), false)));
writer.writeClose(elIt);
}
writer.writeClose(el);
}
private static void getCustomFieldsXML(XMLWriter writer, SystemConfiguration config) throws IOException {
Properties tags = new Properties();
Element elCustomField = getDocumentFactory().createElement(TAG_CUSTOM_FIELDS);
Element elTmp;
writer.writeOpen(elCustomField);
for (CustomField c: config.getCustomFields()) {
tags.clear();
tags.setProperty(TAG_CUSTOM_FIELD_LABEL, ITrackerResources.escapeUnicodeString(CustomFieldUtilities.getCustomFieldName(c.getId()), false));
tags.setProperty(TAG_CUSTOM_FIELD_TYPE, String.valueOf(c.getFieldType().name()));
tags.setProperty(TAG_CUSTOM_FIELD_REQUIRED, String.valueOf(c.isRequired()));
tags.setProperty(TAG_CUSTOM_FIELD_DATEFORMAT, ITrackerResources.escapeUnicodeString(c.getDateFormat(), false));
tags.setProperty(TAG_CUSTOM_FIELD_SORTOPTIONS, String.valueOf(c.isSortOptionsByName()));
tags.setProperty(TAG_CUSTOM_FIELD_LABEL, ITrackerResources.escapeUnicodeString(CustomFieldUtilities.getCustomFieldName(c.getId()), false));
elTmp = getDocumentFactory().createElement(TAG_CUSTOM_FIELD);
elTmp.addAttribute(ATTR_ID, TAG_CUSTOM_FIELD + c.getId());
elTmp.addAttribute(ATTR_SYSTEMID, String.valueOf(c.getId()));
writer.writeOpen(elTmp);
addCdataPropertyTags(writer, tags);
if (c.getFieldType() == CustomField.Type.LIST) {
Element elOption;
for (CustomFieldValue o: c.getOptions()) {
elOption = getDocumentFactory().createElement(TAG_CUSTOM_FIELD_OPTION);
elOption.addAttribute(ATTR_VALUE, ITrackerResources.escapeUnicodeString(o.getValue(), false));
elOption.add(getDocumentFactory().createCDATA(ITrackerResources.escapeUnicodeString(CustomFieldUtilities.getCustomFieldOptionName(o, null), false)));
writer.write(elOption);
}
}
writer.writeClose(elTmp);
}
writer.writeClose(elCustomField);
}
/**
* Generates an XML block that encapsulates the system configuration for import or export.
* This function will not generate the XML for other models needed for a complete import
* or export.
*
* @param config a SystemConfiguration to generate the XML for
* @return a String containing the XML for the configuration
*/
public static String getConfigurationXML(SystemConfiguration config) {
if (config == null) {
return "";
}
ByteArrayOutputStream os = new ByteArrayOutputStream();
try {
XMLWriter writer = new XMLWriter(os);
getConfigurationXML(writer, config);
writer.close();
return (os.toString("utf-8"));
} catch (Exception e) {
logger.error("could not create xml string", e);
return "";
}
}
}