// Copyright (C) 2003-2009 by Object Mentor, Inc. All rights reserved.
// Released under the terms of the CPL Common Public License version 1.0.
package fitnesse.wiki.fs;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.util.*;
import java.util.logging.Logger;
import fitnesse.util.XmlUtil;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import fitnesse.wiki.PageData;
import fitnesse.wiki.WikiPageLoadException;
import fitnesse.wiki.WikiPageProperty;
/**
* These are the (old) page properties, used by the FileSystemPage.
*/
public class WikiPageProperties extends WikiPageProperty implements Serializable {
private static final Logger LOG = Logger.getLogger(WikiPageProperties.class.getName());
private static final long serialVersionUID = 1L;
public WikiPageProperties() {
}
public WikiPageProperties(InputStream inputStream) {
this();
loadFromXmlStream(inputStream);
}
public WikiPageProperties(Element rootElement) {
this();
loadFromRootElement(rootElement);
}
public WikiPageProperties(WikiPageProperty that) {
super(that);
}
public void loadFromXmlStream(InputStream inputStream) {
Document document;
try {
document = XmlUtil.newDocument(inputStream);
} catch (Exception e) {
throw new WikiPageLoadException("Unable to parse XML from stream", e);
}
Element root = document.getDocumentElement();
loadFromRootElement(root);
}
public void loadFromXml(String xml) {
Document document;
try {
document = XmlUtil.newDocument(xml);
} catch (Exception e) {
throw new WikiPageLoadException("Unable to parse XML from string " + xml, e);
}
Element root = document.getDocumentElement();
loadFromRootElement(root);
}
public void loadFromRootElement(Element root) {
NodeList nodes = root.getChildNodes();
for (int i = 0; i < nodes.getLength(); i++) {
Node node = nodes.item(i);
if (node.getNodeType() != Node.ELEMENT_NODE)
continue;
String key = node.getNodeName();
LoadElement(this, (Element) node, key);
}
}
private void LoadElement(WikiPageProperty context, Element element, String key) {
WikiPageProperty newProperty = new WikiPageProperty();
context.set(key, newProperty);
NodeList nodes = element.getChildNodes();
if (element.hasAttribute("value"))
newProperty.setValue(element.getAttribute("value"));
else if (nodes.getLength() == 1)
newProperty.setValue(nodes.item(0).getNodeValue());
for (int i = 0; i < nodes.getLength(); i++) {
Node childNode = nodes.item(i);
if (childNode instanceof Element)
LoadElement(newProperty, (Element) childNode, childNode.getNodeName());
}
}
public String toXml() throws IOException {
Document document = XmlUtil.newDocument();
document.appendChild(makeRootElement(document));
return XmlUtil.xmlAsString(document);
}
public Element makeRootElement(Document document) {
Element root = document.createElement("properties");
List<String> keys = new ArrayList<>(keySet());
Collections.sort(keys);
for (String key : keys) {
WikiPageProperty childProperty = getProperty(key);
toXml(childProperty, key, document, root);
}
return root;
}
private void toXml(WikiPageProperty context, String key, Document document, Element parent) {
Element element = document.createElement(key);
String value = context.getValue();
if (context.hasChildren()) {
if (value != null)
element.setAttribute("value", value);
Set<String> childKeys = context.keySet();
for (String childKeyAsString : childKeys) {
WikiPageProperty child = context.getProperty(childKeyAsString);
if (child == null) {
LOG.warning("Property key \"" + childKeyAsString + "\" has null value for {" + context + "}");
} else {
toXml(child, childKeyAsString, document, element);
}
}
} else if (value != null)
element.appendChild(document.createTextNode(value));
parent.appendChild(element);
}
@Override
public String toString() {
return super.toString("WikiPageProperties", 0);
}
}