Java tutorial
/* * Copyright (C) 2009 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.sites.liberation.util; import com.google.gdata.util.common.base.Pair; import com.google.gdata.util.common.base.Preconditions; import org.apache.commons.lang.StringEscapeUtils; import java.io.IOException; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.TreeMap; /** * A very simple implementation of an xml element to aid * in generating well formed xhtml pages. * * @author bsimon@google.com (Benjamin Simon) */ public class XmlElement { private final String elementType; private final List<Pair<Object, ChildType>> children; private final Map<String, String> attributes; private static enum ChildType { ELEMENT, TEXT, XML } /** * Creates a new {@code XmlElement} of the given type. * * @param elementType tag name of this element */ public XmlElement(String elementType) { Preconditions.checkNotNull(elementType); this.elementType = elementType; children = new LinkedList<Pair<Object, ChildType>>(); attributes = new TreeMap<String, String>(); } /** * Adds a child XmlElement to this one. * * <p>Children appear in the order in which they are added in the xml output. * </p> */ public XmlElement addElement(XmlElement child) { Preconditions.checkNotNull(child); children.add(new Pair<Object, ChildType>(child, ChildType.ELEMENT)); return this; } /** * Adds a plain text child to this element. The String given is * automatically converted to xml-safe characters. * * <p>Children appear in the order in which they are added in the xml output. * </p> */ public XmlElement addText(String text) { Preconditions.checkNotNull(text); children.add(new Pair<Object, ChildType>(StringEscapeUtils.escapeXml(text), ChildType.TEXT)); return this; } /** * Adds a string of xml as a child to this element. * * <p>Unlike addText(String), the string provided will not be escaped. If the * given String is not well formed, then this element may not be well formed. * </p> */ public XmlElement addXml(String xml) { Preconditions.checkNotNull(xml); children.add(new Pair<Object, ChildType>(xml, ChildType.XML)); return this; } /** * Sets the attribute with the given name to the given value. * * <p>Attributes appear alphabetically by name in the xml output.</p> */ public XmlElement setAttribute(String name, String value) { Preconditions.checkNotNull(name, "name"); Preconditions.checkNotNull(value, "value"); attributes.put(name, StringEscapeUtils.escapeXml(value)); return this; } /** * Appends this XmlElement (and any children) to an Appendable. */ public void appendTo(Appendable a) throws IOException { a.append('<').append(elementType); for (Map.Entry<String, String> attribute : attributes.entrySet()) { a.append(' ').append(attribute.getKey()).append("=\"").append(attribute.getValue()).append("\""); } if (children.isEmpty()) { a.append(" />"); } else { a.append(">"); for (Pair<Object, ChildType> pair : children) { Object child = pair.getFirst(); ChildType type = pair.getSecond(); if (type == ChildType.ELEMENT) { ((XmlElement) child).appendTo(a); } else { a.append((String) child); } } a.append("</").append(elementType).append('>'); } } /** * Returns the String of xml corresponding to this XmlElement. */ @Override public String toString() { StringBuilder builder = new StringBuilder(); try { appendTo(builder); } catch (IOException e) { throw new RuntimeException(e); } return builder.toString(); } @Override public boolean equals(Object other) { if (other instanceof XmlElement) { return toString().equals(other.toString()); } return false; } }