/*
* Freeplane - mind map editor
* Copyright (C) 2008 Dimitry Polivaev
*
* This file author is Dimitry Polivaev
*
* This program is free software: you can redistribute it and/or modify
* it 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.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.freeplane.core.io.xml;
import java.awt.Point;
import java.io.IOException;
import java.io.Writer;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Vector;
import org.freeplane.core.extension.IExtension;
import org.freeplane.core.io.IAttributeWriter;
import org.freeplane.core.io.IElementWriter;
import org.freeplane.core.io.IExtensionAttributeWriter;
import org.freeplane.core.io.IExtensionElementWriter;
import org.freeplane.core.io.ITreeWriter;
import org.freeplane.core.io.ListHashTable;
import org.freeplane.core.io.WriteManager;
import org.freeplane.core.util.LogUtils;
import org.freeplane.n3.nanoxml.XMLElement;
public class TreeXmlWriter implements ITreeWriter {
public static String BooleanToXml(final boolean col) {
return (col) ? "true" : "false";
}
public static String dateToString(final Date date) {
return Long.toString(date.getTime());
}
public static String listToString(final List<?> list) {
final ListIterator<?> it = list.listIterator(0);
final StringBuilder sb = new StringBuilder();
while (it.hasNext()) {
sb.append(it.next().toString()).append(";");
}
return sb.toString();
}
public static String PointToXml(final Point col) {
if (col == null) {
return null;
}
final Vector<String> l = new Vector<String>();
l.add(Integer.toString(col.x));
l.add(Integer.toString(col.y));
return TreeXmlWriter.listToString(l);
}
private boolean elementStarted = false;
final private HashMap<Object, Object> hints;
final private WriteManager writeManager;
private XMLElement xmlElement;
final private XMLWriter xmlwriter;
public void flush() {
xmlwriter.flush();
}
public TreeXmlWriter(final WriteManager writeManager, final Writer writer) {
super();
this.writeManager = writeManager;
xmlwriter = new XMLWriter(writer);
hints = new HashMap<Object, Object>();
}
public void addAttribute(final String key, final double value) {
addAttribute(key, Double.toString(value));
}
public void addAttribute(final String key, final int value) {
addAttribute(key, Integer.toString(value));
}
public void addAttribute(final String key, final String value) {
if (elementStarted) {
throw new RuntimeException("elementStarted");
}
if (null != xmlElement.getAttribute(key, null)) {
LogUtils.warn("attribute \"" + key + "\" already exist with value \"" + value);
return;
}
xmlElement.setAttribute(key, value);
}
public void addComment(final String comment) throws IOException {
xmlwriter.write("<!-- ");
xmlwriter.write(comment);
xmlwriter.write(" -->\n");
}
public void addElement(final Object userObject, final String name) throws IOException {
final XMLElement element = new XMLElement(name);
addElement(userObject, element);
}
@SuppressWarnings("unchecked")
public void addElement(final Object userObject, final XMLElement element) throws IOException {
final boolean isString = userObject instanceof String;
if (elementStarted == false && xmlElement != null) {
xmlwriter.write(xmlElement, ! isString, 0, true, false);
}
final String name = element.getName();
xmlElement = element;
elementStarted = false;
{
final Iterator<IAttributeWriter> iterator = getAttributeWriters().iterator(name);
while (iterator.hasNext()) {
final IAttributeWriter as = iterator.next();
as.writeAttributes(this, userObject, name);
}
if (userObject instanceof List<?>) {
addExtensionAttributes(userObject, (List<IExtension>) userObject);
}
}
if (isString) {
addElementContent((String)userObject);
}
else {
final Iterator<IElementWriter> iterator = getNodeWriters().iterator(name);
while (iterator.hasNext()) {
final IElementWriter nw = iterator.next();
nw.writeContent(this, userObject, name);
}
if (userObject instanceof List<?>) {
addExtensionNodes(userObject, (List<IExtension>) userObject);
}
}
if (elementStarted == false) {
xmlwriter.write(xmlElement, true, 0, true, true);
elementStarted = true;
}
else {
xmlwriter.endElement(name, true);
}
}
public void addElementContent(final String content) throws IOException {
if (content.equals("")) {
return;
}
if (elementStarted == false && xmlElement != null) {
xmlwriter.write(xmlElement, true, 0, true, false);
elementStarted = true;
}
xmlwriter.write(content);
}
public void addExtensionAttributes(final Object map, final Collection<IExtension> extensions) {
final Iterator<IExtension> extensionIterator = extensions.iterator();
while (extensionIterator.hasNext()) {
final IExtension extension = extensionIterator.next();
final Iterator<IExtensionAttributeWriter> writerIterator = writeManager.getExtensionAttributeWriters()
.iterator(extension.getClass());
while (writerIterator.hasNext()) {
writerIterator.next().writeAttributes(this, map, extension);
}
}
}
public void addExtensionNodes(final Object map, final Collection<IExtension> extensions) throws IOException {
final Iterator<IExtension> extensionIterator = extensions.iterator();
while (extensionIterator.hasNext()) {
final IExtension extension = extensionIterator.next();
final Iterator<IExtensionElementWriter> writerIterator = writeManager.getExtensionElementWriters()
.iterator(extension.getClass());
while (writerIterator.hasNext()) {
writerIterator.next().writeContent(this, map, extension);
}
}
}
private ListHashTable<String, IAttributeWriter> getAttributeWriters() {
return writeManager.getAttributeWriters();
}
public Object getHint(final Object key) {
final Object object = hints.get(key);
return object == null ? Boolean.FALSE : object;
}
private ListHashTable<String, IElementWriter> getNodeWriters() {
return writeManager.getElementWriters();
}
public void setHint(final Object key) {
hints.put(key, Boolean.TRUE);
}
public void setHint(final Object key, final Object value) {
hints.put(key, value);
}
}