/* * Copyright (C) 2010 Brockmann Consult GmbH (info@brockmann-consult.de) * * 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 3 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 com.bc.ceres.binding.dom; import com.bc.ceres.core.Assert; import com.thoughtworks.xstream.io.copy.HierarchicalStreamCopier; import com.thoughtworks.xstream.io.xml.PrettyPrintWriter; import com.thoughtworks.xstream.io.xml.XppDomReader; import com.thoughtworks.xstream.io.xml.xppdom.XppDom; import java.io.StringWriter; import java.util.HashMap; public class XppDomElement implements DomElement { private final XppDom xppDom; private DomElement parent; private HashMap<XppDom, DomElement> children; public XppDomElement(String name) { this(new XppDom(name)); } public XppDomElement(XppDom xppDom) { Assert.notNull(xppDom, "xppDom"); Assert.notNull(xppDom.getName(), "xppDom.getName()"); this.xppDom = xppDom; } public XppDom getXppDom() { return xppDom; } @Override public String getName() { return xppDom.getName(); } @Override public String getValue() { return xppDom.getValue(); } @Override public void setValue(String value) { xppDom.setValue(value); } @Override public DomElement getParent() { return parent; } @Override public void setParent(DomElement parent) { if (parent instanceof XppDomElement) { XppDomElement xppDomElement = (XppDomElement) parent; xppDom.setParent(xppDomElement.getXppDom()); } this.parent = parent; } @Override public DomElement[] getChildren() { return getChildren(xppDom.getChildren()); } @Override public DomElement[] getChildren(String elementName) { return getChildren(xppDom.getChildren(elementName)); } @Override public DomElement getChild(int index) { XppDom child = xppDom.getChild(index); if (child == null) { return null; } return getChild(child); } @Override public DomElement getChild(String elementName) { final XppDom child = xppDom.getChild(elementName); if (child == null) { return null; } return getChild(child); } @Override public int getChildCount() { return xppDom.getChildCount(); } @Override public DomElement createChild(String name) { final XppDomElement child = new XppDomElement(new XppDom(name)); addChild(child); return child; } @Override public void addChild(DomElement child) { final XppDom dom; if (child instanceof XppDomElement) { dom = ((XppDomElement) child).getXppDom(); } else { dom = toXppDom(child); } xppDom.addChild(dom); child.setParent(this); } @Override public String[] getAttributeNames() { return xppDom.getAttributeNames(); } @Override public String getAttribute(String attributeName) { return xppDom.getAttribute(attributeName); } @Override public void setAttribute(String name, String value) { xppDom.setAttribute(name, value); } @Override public String toXml() { final StringWriter writer = new StringWriter(); new HierarchicalStreamCopier().copy(new XppDomReader(xppDom), new PrettyPrintWriter(writer)); return writer.toString(); } private XppDom toXppDom(DomElement domElement) { XppDom xppDom = new XppDom(domElement.getName()); if (domElement.getValue() != null) { xppDom.setValue(domElement.getValue()); } String[] names = domElement.getAttributeNames(); for (String name : names) { xppDom.setAttribute(name, domElement.getAttribute(name)); } DomElement[] children = domElement.getChildren(); for (DomElement child : children) { xppDom.addChild(toXppDom(child)); } return xppDom; } private DomElement[] getChildren(XppDom[] xppChildren) { final DomElement[] domElements = new XppDomElement[xppChildren.length]; for (int i = 0; i < xppChildren.length; i++) { domElements[i] = getChild(xppChildren[i]); } return domElements; } private DomElement getChild(XppDom child) { if (children != null) { DomElement childElement = children.get(child); if (childElement != null) { return childElement; } } else { children = new HashMap<XppDom, DomElement>(); } DomElement childElement = new XppDomElement(child); childElement.setParent(this); children.put(child, childElement); return childElement; } }