package org.rr.commons.xml; /* Package Tigase XMPP/Jabber Server * Copyright (C) 2001, 2002, 2003, 2004, 2005 * "Artur Hefczyc" <artur.hefczyc@gmail.com> * * 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 2 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, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * $Rev$ * Last modified by $Author$ * $Date$ */ import static org.rr.commons.utils.StringUtil.EMPTY; import java.io.OutputStream; import java.io.PrintStream; import java.util.List; import org.rr.commons.utils.ListUtils; /** * This is temporary code used for testing purposes only. It is subject to change or remove at any time of server development. It has been created to format * <em>XML</em> files to make them easier to read and modify by a human. With current <code>XMLDB</code> implementation however it is not necessary to use this * formatter for configuration files and user repositories as they are saved in proper format. * * <p> * Created: Thu Oct 21 14:49:41 2004 * </p> * * @author <a href="mailto:artur.hefczyc@gmail.com">Artur Hefczyc</a> * @version $Rev$ */ class XMLFormatter implements SimpleHandler { private PrintStream output = null; private int indentSpaces = 0; private boolean cdataWritten = false; private boolean openedElement = false; private Object parserData = null; // config private int maxCDataLength = -1; private int indent = 2; /** * Creates a new <code>XMLFormatter</code> instance. * */ public XMLFormatter(OutputStream out) { output = new PrintStream(out); } // Implementation of tigase.xml.SimpleHandler /** * Describe <code>error</code> method here. * */ public void error() { } private void indent() { for (int idx = 0; idx < indentSpaces; idx++) { output.print(" "); } } /** * Describe <code>startElement</code> method here. * * @param name * a <code>StringBuilder</code> value * @param att_names * a <code>StringBuilder[]</code> value * @param att_values * a <code>StringBuilder[]</code> value */ public void startElement(final StringBuilder name, final StringBuilder[] att_names, final StringBuilder[] att_values) { if (openedElement) { output.println(">"); } else { output.println(EMPTY); } indent(); output.print("<" + name); if (att_names != null) { for (int i = 0; i < att_names.length; i++) { if (att_names[i] != null) { output.print(" " + att_names[i] + "='" + att_values[i] + "'"); } } } indentSpaces += 2; cdataWritten = false; openedElement = true; } /** * Describe <code>elementCData</code> method here. * * @param cdata * a <code>StringBuilder</code> value */ public void elementCData(final StringBuilder cdata) { output.print(">"); openedElement = false; if(cdata.indexOf("\n")!=-1) { //do not format already formatted values List<String> splitted = ListUtils.split(cdata.toString(), "\n"); for (String split : splitted) { output.print('\n'); indent(); output.print(split.trim()); } } else if (getMaxCDataLength() > 0) { for (int srcBegin = 0; srcBegin < cdata.length(); srcBegin += maxCDataLength) { output.print('\n'); indent(); if (cdata.length() >= srcBegin + maxCDataLength) { CharSequence subSequence = cdata.subSequence(srcBegin, srcBegin + maxCDataLength); output.print(subSequence); } else { output.print(cdata.subSequence(srcBegin, cdata.length())); } } } else { output.print(cdata); } cdataWritten = true; } /** * Describe <code>endElement</code> method here. * * @param name * a <code>StringBuilder</code> value */ public void endElement(final StringBuilder name) { if (cdataWritten) { output.println(EMPTY); for (int idx = 0; idx < (indentSpaces - 2); idx++) { output.print(" "); } output.print("</" + name + ">"); } else { output.print("/>"); } indentSpaces -= 2; cdataWritten = true; openedElement = false; } /** * Describe <code>otherXML</code> method here. * * @param other * a <code>StringBuilder</code> value */ public void otherXML(final StringBuilder other) { output.println("<" + other + ">"); } /** * Describe <code>saveParserState</code> method here. * * @param object * an <code>Object</code> value */ public void saveParserState(final Object object) { parserData = object; } /** * Describe <code>restoreParserState</code> method here. * * @return an <code>Object</code> value */ public Object restoreParserState() { return parserData; } public void outputExtraData(String extra) { output.println(extra); } public int getMaxCDataLength() { return maxCDataLength; } public void setMaxCDataLength(int maxCDataLength) { this.maxCDataLength = maxCDataLength; } public int getIndent() { return indent; } public void setIndent(int indent) { this.indent = indent; } } // XMLFormatter