org.jboss.rusheye.result.writer.PrettyXMLStreamWriter.java Source code

Java tutorial

Introduction

Here is the source code for org.jboss.rusheye.result.writer.PrettyXMLStreamWriter.java

Source

/**
 * JBoss, Home of Professional Open Source
 * Copyright ${year}, Red Hat, Inc. and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This 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 software 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.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package org.jboss.rusheye.result.writer;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

import javax.xml.stream.XMLStreamWriter;

import org.apache.commons.lang.StringUtils;
import org.jboss.rusheye.RushEye;

public class PrettyXMLStreamWriter implements InvocationHandler {

    int indentation = 0;
    boolean simpleContent;
    XMLStreamWriter writer;
    List<WriteAttribute> writeAttributes = new LinkedList<WriteAttribute>();

    public PrettyXMLStreamWriter(XMLStreamWriter writer) {
        this.writer = writer;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        Object result;

        // namespace handling
        if (args != null) {
            for (int i = 0; i < args.length; i++) {
                if (RushEye.NAMESPACE_VISUAL_SUITE.equals(args[i])) {
                    args[i] = RushEye.NAMESPACE_VISUAL_SUITE_RESULT;
                }
            }
        }
        if ("writeNamespace".equals(method.getName()) || "writeDefaultNamespace".equals(method.getName())) {
            if (indentation > 1) {
                return null;
            }
        }

        // attribute reordering (alphabethical order)
        if ("writeAttribute".equals(method.getName())) {
            writeAttributes.add(new WriteAttribute(method, args));
            return null;
        } else if (!writeAttributes.isEmpty()) {
            Collections.sort(writeAttributes);
            for (WriteAttribute writeAttribute : writeAttributes) {
                invoke(writeAttribute.method, writeAttribute.args);
            }
            writeAttributes.clear();
        }

        // handling of empty elements
        if ("writeStartElement".equals(method.getName())) {
            writer.writeCharacters("\n");
            writer.writeCharacters(StringUtils.repeat("\t", indentation));
            indentation++;
        } else if ("writeEndElement".equals(method.getName())) {
            indentation--;
            if (!simpleContent) {
                writer.writeCharacters("\n");
                writer.writeCharacters(StringUtils.repeat("\t", indentation));
            }
        } else if ("writeEmptyElement".equals(method.getName())) {
            writer.writeCharacters("\n");
            writer.writeCharacters(StringUtils.repeat("\t", indentation));
        }
        // decision about simple content (incl. empty elements)
        if ("writeStartElement".equals(method.getName())) {
            simpleContent = true;
        } else if ("writeCharacters".equals(method.getName()) || "writeAttribute".equals(method.getName())) {
            // intentionally left blank
        } else {
            simpleContent = false;
        }

        result = invoke(method, args);

        return result;
    }

    private Object invoke(Method method, Object[] args)
            throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
        return method.invoke(writer, args);
    }

    public static XMLStreamWriter pretty(XMLStreamWriter writer) {
        return (XMLStreamWriter) Proxy.newProxyInstance(writer.getClass().getClassLoader(),
                new Class[] { XMLStreamWriter.class }, new PrettyXMLStreamWriter(writer));
    }

    private class WriteAttribute implements Comparable<WriteAttribute> {
        Method method;
        Object[] args;
        String attributeName;

        public WriteAttribute(Method method, Object[] args) {
            this.method = method;
            this.args = args;
            attributeName = (String) args[args.length - 2];
        }

        @Override
        public int compareTo(WriteAttribute o) {
            return attributeName.compareTo(o.attributeName);
        }
    }
}