/*
 * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

package sun.jvm.hotspot.utilities;

import java.io.*;
import java.util.*;
import sun.jvm.hotspot.oops.*;
import sun.jvm.hotspot.runtime.*;

/**
 * <p>This class writes Java heap in Graph eXchange Language (GXL)
 * format. GXL is an open standard for serializing arbitrary graphs in
 * XML syntax.</p>
 *
 * <p>A GXL document contains one or more graphs. A graph contains
 * nodes and edges. Both nodes and edges can have attributes. graphs,
 * nodes, edges and attributes are represented by XML elements graph,
 * node, edge and attr respectively. Attributes can be typed. GXL
 * supports locator, bool, int, float, bool, string, enum as well as
 * set, seq, bag, tup types. Nodes must have a XML attribute 'id' that
 * is unique id of the node in the GXL document. Edges must have
 * 'from' and 'to' XML attributes that are ids of from and to nodes.</p>
 *
 * <p>Java heap to GXL document mapping:</p>
 * <ul>
 * <li>Java object - GXL node.
 * <li>Java primitive field - GXL attribute (type mapping below).
 * <li>Java reference field - GXL edge from referee to referent node.
 * <li>Java primitive array - GXL node with seq type attribute.
 * <li>Java char array - GXL node with one attribute of string type.
 * <li>Java object array - GXL node and 'length' edges.
 * </ul>
 *
 * <p>Java primitive to GXL type mapping:</p>
 * <ul>
 * <li>Java byte, int, short, long - GXL int attribute
 * <li>Java float, double - GXL float attribute
 * <li>Java boolean - GXL bool atttribute
 * <li>Java char - GXL string attribute
 * </ul>
 *
 * Exact Java primitive type code is written in 'kind' attribute of
 * 'attr' element.  Type code is specified in JVM spec. second edition
 * section 4.3.2 (Field Descriptor).
 *
 * @see <a href="http://www.gupro.de/GXL/">GXL</a>
 * @see <a href="http://www.gupro.de/GXL/dtd/dtd.html">GXL DTD</a>
 */

public class HeapGXLWriter extends AbstractHeapGraphWriter {
    public void write(String fileName) throws IOException {
        out = new PrintWriter(new BufferedWriter(new FileWriter(fileName)));
        super.write();
        if (out.checkError()) {
            throw new IOException();
        }
        out.flush();
    }

    protected void writeHeapHeader() throws IOException {
        // XML processing instruction
        out.print("<?xml version='1.0' encoding='");
        out.print(ENCODING);
        out.println("'?>");

        out.println("<gxl>");
        out.println("<graph id='JavaHeap'>");

        // document properties
        writeAttribute("creation-date", "string", new Date().toString());

        // write VM info
        writeVMInfo();

        // emit a node for null
        out.print("<node id='");
        out.print(getID(null));
        out.println("'/>");
    }

    protected void writeObjectHeader(Oop oop) throws IOException  {
        refFields = new ArrayList();
        isArray = oop.isArray();

        // generate an edge for instanceof relation
        // between object node and it's class node.
        writeEdge(oop, oop.getKlass().getJavaMirror(), "instanceof");

        out.print("<node id='");
        out.print(getID(oop));
        out.println("'>");
    }

    protected void writeObjectFooter(Oop oop) throws IOException  {
        out.println("</node>");

        // write the reference fields as edges
        for (Iterator itr = refFields.iterator(); itr.hasNext();) {
            OopField field = (OopField) itr.next();
            Oop ref = field.getValue(oop);

            String name = field.getID().getName();
            if (isArray) {
                // for arrays elements we use element<index> pattern
                name = "element" + name;
            } else {
                name = identifierToXMLName(name);
            }
            writeEdge(oop, ref, name);
        }
        refFields = null;
    }

    protected void writeObjectArray(ObjArray array) throws IOException {
        writeObjectHeader(array);
        writeArrayLength(array);
        writeObjectFields(array);
        writeObjectFooter(array);
    }

    protected void writePrimitiveArray(TypeArray array)
        throws IOException  {
        writeObjectHeader(array);
        // write array length
        writeArrayLength(array);
        // write array elements
        out.println("\t<attr name='elements'>");
        TypeArrayKlass klass = (TypeArrayKlass) array.getKlass();
        if (klass.getElementType() == TypeArrayKlass.T_CHAR) {
            // char[] special treatment -- write it as string
            out.print("\t<string>");
            out.print(escapeXMLChars(OopUtilities.charArrayToString(array)));
            out.println("</string>");
        } else {
            out.println("\t<seq>");
            writeObjectFields(array);
            out.println("\t</seq>");
        }
        out.println("\t</attr>");
        writeObjectFooter(array);
    }

    protected void writeClass(Instance instance) throws IOException  {
        writeObjectHeader(instance);
        Klass reflectedType = java_lang_Class.asKlass(instance);
        boolean isInstanceKlass = (reflectedType instanceof InstanceKlass);
        // reflectedType is null for primitive types (int.class etc).
        if (reflectedType != null) {
            Symbol name = reflectedType.getName();
            if (name != null) {
                // write class name as an attribute
                writeAttribute("class-name", "string", name.asString());
            }
            if (isInstanceKlass) {
                // write object-size as an attribute
                long sizeInBytes = reflectedType.getLayoutHelper();
                writeAttribute("object-size", "int",
                               Long.toString(sizeInBytes));
                // write static fields of this class.
                writeObjectFields((InstanceKlass)reflectedType);
            }
        }
        out.println("</node>");

        // write edges for super class and direct interfaces
        if (reflectedType != null) {
            Klass superType = reflectedType.getSuper();
            Oop superMirror = (superType == null)?
                              null : superType.getJavaMirror();
            writeEdge(instance, superMirror, "extends");
            if (isInstanceKlass) {
                // write edges for directly implemented interfaces
                InstanceKlass ik = (InstanceKlass) reflectedType;
                KlassArray interfaces = ik.getLocalInterfaces();
                final int len = interfaces.length();
                for (int i = 0; i < len; i++) {
                    Klass k = interfaces.getAt(i);
                    writeEdge(instance, k.getJavaMirror(), "implements");
                }

                // write loader
                Oop loader = ik.getClassLoader();
                writeEdge(instance, loader, "loaded-by");

                // write signers NYI
                // Oop signers = ik.getJavaMirror().getSigners();
                writeEdge(instance, null, "signed-by");

                // write protection domain NYI
                // Oop protectionDomain = ik.getJavaMirror().getProtectionDomain();
                writeEdge(instance, null, "protection-domain");

                // write edges for static reference fields from this class
                for (Iterator itr = refFields.iterator(); itr.hasNext();) {
                    OopField field = (OopField) itr.next();
                    Oop ref = field.getValue(reflectedType);
                    String name = field.getID().getName();
                    writeEdge(instance, ref, identifierToXMLName(name));
                }
            }
        }
        refFields = null;
    }

    protected void writeReferenceField(Oop oop, OopField field)
        throws IOException {
        refFields.add(field);
    }

    protected void writeByteField(Oop oop, ByteField field)
        throws IOException {
        writeField(field, "int", "B", Byte.toString(field.getValue(oop)));
    }

    protected void writeCharField(Oop oop, CharField field)
        throws IOException {
        writeField(field, "string", "C",
                   escapeXMLChars(Character.toString(field.getValue(oop))));
    }

    protected void writeBooleanField(Oop oop, BooleanField field)
        throws IOException {
        writeField(field, "bool", "Z", Boolean.toString(field.getValue(oop)));
    }

    protected void writeShortField(Oop oop, ShortField field)
        throws IOException {
        writeField(field, "int", "S", Short.toString(field.getValue(oop)));
    }

    protected void writeIntField(Oop oop, IntField field)
        throws IOException {
        writeField(field, "int", "I", Integer.toString(field.getValue(oop)));
    }

    protected void writeLongField(Oop oop, LongField field)
        throws IOException {
        writeField(field, "int", "J", Long.toString(field.getValue(oop)));
    }

    protected void writeFloatField(Oop oop, FloatField field)
        throws IOException {
        writeField(field, "float", "F", Float.toString(field.getValue(oop)));
    }

    protected void writeDoubleField(Oop oop, DoubleField field)
        throws IOException {
        writeField(field, "float", "D", Double.toString(field.getValue(oop)));
    }

    protected void writeHeapFooter() throws IOException  {
        out.println("</graph>");
        out.println("</gxl>");
    }

    //-- Internals only below this point

    // Java identifier to XML NMTOKEN type string
    private static String identifierToXMLName(String name) {
        // for now, just replace '$' with '_'
        return name.replace('$', '_');
    }

    // escapes XML meta-characters and illegal characters
    private static String escapeXMLChars(String s) {
        // FIXME: is there a better way or API?
        StringBuffer result = null;
        for(int i = 0, max = s.length(), delta = 0; i < max; i++) {
            char c = s.charAt(i);
            String replacement = null;
            if (c == '&') {
                replacement = "&amp;";
            } else if (c == '<') {
                replacement = "&lt;";
            } else if (c == '>') {
                replacement = "&gt;";
            } else if (c == '"') {
                replacement = "&quot;";
            } else if (c == '\'') {
                replacement = "&apos;";
            } else if (c <  '\u0020' || (c > '\ud7ff' && c < '\ue000') ||
                       c == '\ufffe' || c == '\uffff') {
                // These are illegal in XML -- put these in a CDATA section.
                // Refer to section 2.2 Characters in XML specification at
                // http://www.w3.org/TR/2004/REC-xml-20040204/
                replacement = "<![CDATA[&#x" +
                    Integer.toHexString((int)c) + ";]]>";
            }

            if (replacement != null) {
                if (result == null) {
                    result = new StringBuffer(s);
                }
                result.replace(i + delta, i + delta + 1, replacement);
                delta += (replacement.length() - 1);
            }
        }
        if (result == null) {
            return s;
        }
        return result.toString();
    }

    private static String getID(Oop oop) {
        // address as unique id for node -- prefixed by "ID_".
        if (oop == null) {
            return "ID_NULL";
        } else {
            return "ID_" + oop.getHandle().toString();
        }
    }

    private void writeArrayLength(Array array) throws IOException {
        writeAttribute("length", "int",
                       Integer.toString((int) array.getLength()));
    }

    private void writeAttribute(String name, String type, String value) {
        out.print("\t<attr name='");
        out.print(name);
        out.print("'><");
        out.print(type);
        out.print('>');
        out.print(value);
        out.print("</");
        out.print(type);
        out.println("></attr>");
    }

    private void writeEdge(Oop from, Oop to, String name) throws IOException {
        out.print("<edge from='");
        out.print(getID(from));
        out.print("' to='");
        out.print(getID(to));
        out.println("'>");
        writeAttribute("name", "string", name);
        out.println("</edge>");
    }

    private void writeField(Field field, String type, String kind,
                            String value) throws IOException  {
        // 'type' is GXL type of the attribute
        // 'kind' is Java type code ("B", "C", "Z", "S", "I", "J", "F", "D")
        if (isArray) {
            out.print('\t');
        } else {
            out.print("\t<attr name='");
            String name = field.getID().getName();
            out.print(identifierToXMLName(name));
            out.print("' kind='");
            out.print(kind);
            out.print("'>");
        }
        out.print('<');
        out.print(type);
        out.print('>');
        out.print(value);
        out.print("</");
        out.print(type);
        out.print('>');
        if (isArray) {
            out.println();
        } else {
            out.println("</attr>");
        }
    }

    private void writeVMInfo() throws IOException {
        VM vm = VM.getVM();
        writeAttribute("vm-version", "string", vm.getVMRelease());
        writeAttribute("vm-type", "string",
                       (vm.isClientCompiler())? "client" :
                       ((vm.isServerCompiler())? "server" : "core"));
        writeAttribute("os", "string", vm.getOS());
        writeAttribute("cpu", "string", vm.getCPU());
        writeAttribute("pointer-size", "string",
                       Integer.toString((int)vm.getOopSize() * 8));
    }

    // XML encoding that we'll use
    private static final String ENCODING = "UTF-8";

    // reference fields of currently visited object
    private List/*<OopField>*/ refFields;
    // are we writing an array now?
    private boolean isArray;
    private PrintWriter out;
}
