alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (HeapGXLWriter.java)

This example Java source code file (HeapGXLWriter.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

arraylist, booleanfield, doublefield, floatfield, instanceklass, ioexception, iterator, list\/\*, oop, oopfield, printwriter, string, stringbuffer, typearrayklass, util

The HeapGXLWriter.java Java example source code

/*
 * 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:

* <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:

* <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 * @see <a href="http://www.gupro.de/GXL/dtd/dtd.html">GXL DTD */ 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 = "&"; } else if (c == '<') { replacement = "<"; } else if (c == '>') { replacement = ">"; } else if (c == '"') { replacement = """; } else if (c == '\'') { replacement = "'"; } 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; }

Other Java examples (source code examples)

Here is a short list of links related to this Java HeapGXLWriter.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.