/** * Copyright (c) 2000-present Liferay, Inc. All rights reserved. * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library 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 Lesser General Public License for more * details. */ package com.liferay.portal.kernel.xml.simple; import com.liferay.portal.kernel.util.HtmlUtil; import com.liferay.portal.kernel.util.StringBundler; import com.liferay.portal.kernel.util.StringPool; import java.util.LinkedList; /** * @author Shuyang Zhou * @author Brian Wing Shun Chan */ public class Element { public Element(Element parentElement, String name) { this(parentElement, name, null); } public Element(Element parentElement, String name, String text) { if (parentElement._elementClosed) { throw new IllegalArgumentException("Parent element is closed"); } _parentElement = parentElement; _name = name; _text = _formatText(text); _elementStack = parentElement._elementStack; _stringBundler = parentElement._stringBundler; _appendChildElement(); } public Element(String name) { this(name, null, true); } public Element(String name, boolean addHeader) { this(name, null, addHeader); } public Element(String name, String text) { this(name, text, true); } public Element(String name, String text, boolean addHeader) { _name = name; _text = _formatText(text); _elementStack = new LinkedList<>(); _stringBundler = new StringBundler(); if (addHeader) { _stringBundler.append(_XML_HEADER); } _openElement(this); } public void addAttribute(String name, String value) { if (_openTagClosed) { throw new IllegalStateException("Element is closed"); } _stringBundler.append(StringPool.SPACE); _stringBundler.append(name); _stringBundler.append(_EQUAL_QUOTE); _stringBundler.append(value); _stringBundler.append(StringPool.QUOTE); } public Element addElement(String name) { return addElement(name, null); } public Element addElement(String name, boolean text) { return addElement(name, String.valueOf(text)); } public Element addElement(String name, double text) { return addElement(name, String.valueOf(text)); } public Element addElement(String name, float text) { return addElement(name, String.valueOf(text)); } public Element addElement(String name, int text) { return addElement(name, String.valueOf(text)); } public Element addElement(String name, long text) { return addElement(name, String.valueOf(text)); } public Element addElement(String name, Object text) { return addElement(name, String.valueOf(text)); } public Element addElement(String name, short text) { return addElement(name, String.valueOf(text)); } public Element addElement(String name, String text) { return new Element(this, name, text); } public String getName() { return _name; } public Element getParentElement() { return _parentElement; } public String getText() { return _text; } public boolean isRootElement() { if (_parentElement == null) { return true; } else { return false; } } public String toXMLString() { if (_parentElement != null) { throw new IllegalStateException( "XML string can only generated from a root element"); } if (_xmlString == null) { _flushPendingOpenElements(); _xmlString = _stringBundler.toString(); } return _xmlString; } private void _appendChildElement() { Element topElement = _elementStack.getLast(); while ((topElement != _parentElement) && (topElement != null)) { // Close previous sibling elements _closeElement(topElement); _elementStack.removeLast(); topElement = _elementStack.getLast(); } if (topElement == _parentElement) { // Append current element to its parent _closeOpenTag(topElement); _openElement(this); } else { throw new IllegalArgumentException( "The parent element does not exist"); } } private void _closeElement(Element element) { _closeOpenTag(element); _stringBundler.append(_CLOSE_PRE); _stringBundler.append(element._name); _stringBundler.append(_CLOSE_POST); element._elementClosed = true; } private void _closeOpenTag(Element element) { if (element._openTagClosed == false) { _stringBundler.append(_OPEN_POST); if (element._text != null) { _stringBundler.append(element._text); } element._openTagClosed = true; } } private void _flushPendingOpenElements() { while (!_elementStack.isEmpty()) { _closeElement(_elementStack.removeLast()); } } private String _formatText(String text) { return HtmlUtil.escape(text); } private void _openElement(Element element) { _stringBundler.append(_OPEN_PRE).append(element._name); _elementStack.addLast(element); } private static final String _CLOSE_POST = ">"; private static final String _CLOSE_PRE = "</"; private static final String _EQUAL_QUOTE = "=\""; private static final String _OPEN_POST = ">"; private static final String _OPEN_PRE = "<"; private static final String _XML_HEADER = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; private boolean _elementClosed; private final LinkedList<Element> _elementStack; private final String _name; private boolean _openTagClosed; private Element _parentElement; private final StringBundler _stringBundler; private final String _text; private String _xmlString; }