// 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; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Collections; import java.util.Date; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import util.XmlUtil; public class PageXmlizer { private static SimpleDateFormat dateFormat = WikiPageProperty.getTimeFormat(); private LinkedList<XmlizePageCondition> pageConditions = new LinkedList<XmlizePageCondition>(); public Document xmlize(WikiPage page) { Document document = XmlUtil.newDocument(); Element pageElement = createXmlFromPage(document, page); document.appendChild(pageElement); return document; } public void deXmlize(Document doc, WikiPage context, XmlizerPageHandler handler) { Element pageElement = doc.getDocumentElement(); addChildFromXml(pageElement, context, handler); } public void deXmlizeSkippingRootLevel(Document document, WikiPage context, XmlizerPageHandler handler) { Element pageElement = document.getDocumentElement(); addChildrenFromXml(pageElement, context, handler); } public Document xmlize(PageData data) { Document document = XmlUtil.newDocument(); Element dataElement = document.createElement("data"); XmlUtil.addCdataNode(document, dataElement, "content", data.getContent()); Element propertiesElement = data.getProperties().makeRootElement(document); dataElement.appendChild(propertiesElement); document.appendChild(dataElement); return document; } public PageData deXmlizeData(Document document) { PageData data = new PageData(new WikiPageDummy()); Element dataElement = document.getDocumentElement(); String content = XmlUtil.getLocalTextValue(dataElement, "content"); data.setContent(content); Element propertiesElement = XmlUtil.getLocalElementByTagName(dataElement, "properties"); WikiPageProperties properties = new WikiPageProperties(propertiesElement); data.setProperties(properties); return data; } private void addPageXmlToElement(Document document, Element context, WikiPage page) { if (pageMeetsConditions(page)) context.appendChild(createXmlFromPage(document, page)); } private boolean pageMeetsConditions(WikiPage page) { for (Iterator<XmlizePageCondition> iterator = pageConditions.iterator(); iterator.hasNext();) { XmlizePageCondition xmlizePageCondition = iterator.next(); if (!xmlizePageCondition.canBeXmlized(page)) return false; } return true; } private Element createXmlFromPage(Document document, WikiPage page) { Element pageElement = document.createElement("page"); XmlUtil.addTextNode(document, pageElement, "name", page.getName()); addLastModifiedTag(page, document, pageElement); addXmlFromChildren(page, document, pageElement); return pageElement; } private void addLastModifiedTag(WikiPage page, Document document, Element pageElement) { Date lastModificationTime = page.getData().getProperties().getLastModificationTime(); String lastModifiedTimeString = dateFormat.format(lastModificationTime); XmlUtil.addTextNode(document, pageElement, "lastModified", lastModifiedTimeString); } private void addXmlFromChildren(WikiPage page, Document document, Element pageElement) { Element childrenElement = document.createElement("children"); List<WikiPage> children = page.getChildren(); Collections.sort(children); for (Iterator<WikiPage> iterator = children.iterator(); iterator.hasNext();) { WikiPage child = iterator.next(); addPageXmlToElement(document, childrenElement, child); } pageElement.appendChild(childrenElement); } private void addChildFromXml(Element pageElement, WikiPage context, XmlizerPageHandler handler) { String name = XmlUtil.getTextValue(pageElement, "name"); String modifiedDateString = XmlUtil.getTextValue(pageElement, "lastModified"); Date modifiedDate; try { modifiedDate = modifiedDateString == null ? new Date(0) : dateFormat.parse(modifiedDateString); } catch (ParseException e) { modifiedDate = new Date(0); } WikiPage childPage = context.getChildPage(name); if (childPage == null) childPage = context.addChildPage(name); handler.enterChildPage(childPage, modifiedDate); addChildrenFromXml(pageElement, childPage, handler); handler.exitPage(); } private void addChildrenFromXml(Element pageElement, WikiPage contextPage, XmlizerPageHandler handler) { Element childrenElement = XmlUtil.getLocalElementByTagName(pageElement, "children"); NodeList childNodes = childrenElement.getChildNodes(); for (int i = 0; i < childNodes.getLength(); i++) { Node node = childNodes.item(i); if ("page".equals(node.getNodeName())) addChildFromXml((Element) node, contextPage, handler); } } public void addPageCondition(XmlizePageCondition xmlizePageCondition) { pageConditions.add(xmlizePageCondition); } }