/*******************************************************************************
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package org.apache.kato.katoview.commands.helpers;
import java.lang.reflect.Modifier;
import java.util.Iterator;
import java.util.ArrayList;
import java.util.List;
import javax.tools.diagnostics.image.CorruptDataException;
import javax.tools.diagnostics.image.ImageSection;
import javax.tools.diagnostics.image.MemoryAccessException;
import javax.tools.diagnostics.runtime.java.JavaClass;
import javax.tools.diagnostics.runtime.java.JavaField;
import javax.tools.diagnostics.runtime.java.JavaMethod;
import javax.tools.diagnostics.runtime.java.JavaObject;
import javax.tools.diagnostics.runtime.java.JavaRuntime;
import org.apache.kato.katoview.Output;
public class ClassOutput {
public static void printStaticFields(JavaClass jc, Output out)
{
// if the class name refers to an array, return because there are no fields
try {
if (jc.isArray()) {
return;
}
} catch (CorruptDataException cde) {
out.print("\t <can't determine if class is array; assuming it's not>\n\n");
}
String className;
try {
className = jc.getName();
} catch (CorruptDataException cde) {
className = null;
}
// we've found a class, so we'll print out its static fields
boolean found = false;
Iterator itField = jc.getDeclaredFields().iterator();
while (itField.hasNext())
{
JavaField jf = (JavaField)itField.next();
boolean isStatic;
try {
isStatic = Modifier.isStatic(jf.getModifiers());
} catch (CorruptDataException e) {
out.print("\t <error while getting modifier for field \"");
try {
out.print(jf.getName());
} catch (CorruptDataException d) {
out.print(Exceptions.getCorruptDataExceptionString());
}
out.print("\", " + Exceptions.getCorruptDataExceptionString() + ">");
isStatic = false;
}
if (isStatic)
{
if (!found)
{
out.print("\t static fields for \"" + className + "\"\n");
}
found = true;
printStaticFieldData(jf, out);
}
}
if (found)
out.print("\n");
else
out.print("\t \"" + className + "\" has no static fields\n\n");
}
public static void printNonStaticFields(JavaClass jc, Output out)
{
// if the class name refers to an array, return because there are no fields
try {
if (jc.isArray()) {
return;
}
} catch (CorruptDataException cde) {
out.print("\t <can't determine if class is array; assuming it's not>\n\n");
}
String className;
try {
className = jc.getName();
} catch (CorruptDataException cde) {
className = null;
}
// we've found a class, so we'll print out its static fields
boolean found = false;
Iterator itField = jc.getDeclaredFields().iterator();
while (itField.hasNext())
{
JavaField jf = (JavaField)itField.next();
boolean isStatic;
try {
isStatic = Modifier.isStatic(jf.getModifiers());
} catch (CorruptDataException e) {
out.print("\t <error while getting modifier for field \"");
try {
out.print(jf.getName());
} catch (CorruptDataException d) {
out.print(Exceptions.getCorruptDataExceptionString());
}
out.print("\", " + Exceptions.getCorruptDataExceptionString() + ">");
isStatic = false;
}
if (!isStatic)
{
if (!found)
{
out.print("\t non-static fields for \"" + className + "\"\n");
}
found = true;
printNonStaticFieldData(null, jf, out);
}
}
if (found)
out.print("\n");
else
out.print("\t \"" + className + "\" has no non-static fields\n\n");
}
public static void printFields(JavaObject jo, JavaClass jc, JavaRuntime jr, Output out)
{
boolean array;
try {
array = jo.isArray();
} catch (CorruptDataException e) {
out.print("\t <cannot determine if above object is array (" +
Exceptions.getCorruptDataExceptionString() + "); "
+ "we will assume it is not an array>\n");
array = false;
}
if (array)
{
String componentType;
int arraySize;
try {
componentType = jc.getComponentType().getName();
} catch (CorruptDataException e) {
out.print("\t <cannot determine what type of array this is (" +
Exceptions.getCorruptDataExceptionString() + ")>\n");
return;
}
try {
arraySize = jo.getArraySize();
} catch (CorruptDataException e) {
out.print("\t <cannot determine the size of the array (" +
Exceptions.getCorruptDataExceptionString() + ")>\n");
return;
}
Object dst = null;
if (componentType.equals("boolean")) {
dst = new boolean[arraySize];
} else if (componentType.equals("byte")) {
dst = new byte[arraySize];
} else if (componentType.equals("char")) {
dst = new char[arraySize];
} else if (componentType.equals("short")) {
dst = new short[arraySize];
} else if (componentType.equals("int")) {
dst = new int[arraySize];
} else if (componentType.equals("long")) {
dst = new long[arraySize];
} else if (componentType.equals("float")) {
dst = new float[arraySize];
} else if (componentType.equals("double")) {
dst = new double[arraySize];
} else {
dst = new JavaObject[arraySize];
}
try {
jo.arraycopy(0, dst, 0, arraySize);
} catch (CorruptDataException e) {
out.print("\t <cannot copy data from the array (" +
Exceptions.getCorruptDataExceptionString() + ")>\n");
return;
} catch (MemoryAccessException e) {
out.print("\t <cannot copy data from the array (" +
Exceptions.getMemoryAccessExceptionString() + ")>\n");
return;
}
for (int i = 0; i < arraySize; i++)
{
out.print("\t " + i + ":\t");
if (componentType.equals("boolean")) {
out.print(Utils.getVal(new Boolean(((boolean[])dst)[i])));
} else if (componentType.equals("byte")) {
out.print(Utils.getVal(new Byte(((byte[])dst)[i])));
} else if (componentType.equals("char")) {
out.print(Utils.getVal(new Character(((char[])dst)[i])));
} else if (componentType.equals("short")) {
out.print(Utils.getVal(new Short(((short[])dst)[i])));
} else if (componentType.equals("int")) {
out.print(Utils.getVal(new Integer(((int[])dst)[i])));
} else if (componentType.equals("long")) {
out.print(Utils.getVal(new Long(((long[])dst)[i])));
} else if (componentType.equals("float")) {
out.print(Utils.getVal(new Float(((float[])dst)[i])));
} else if (componentType.equals("double")) {
out.print(Utils.getVal(new Double(((double[])dst)[i])));
} else {
out.print(Utils.getVal(((JavaObject[])dst)[i]));
}
out.print("\n");
}
}
else
{
JavaClass initialJC = jc;
List classList = new ArrayList();
while (jc != null){
classList.add(jc);
try {
jc = jc.getSuperclass();
} catch (CorruptDataException d) {
jc = null;
}
}
for (int i = (classList.size()-1); i >=0 ; i--){
jc = (JavaClass)classList.get(i);
Iterator itField = jc.getDeclaredFields().iterator();
if (itField.hasNext()){
if (jc.equals(initialJC)){
out.print("\t declared fields:\n");
} else {
out.print("\t fields inherited from \"");
try {
out.print(jc.getName() + "\":\n");
} catch (CorruptDataException d) {
out.print(Exceptions.getCorruptDataExceptionString());
}
}
}
while (itField.hasNext())
{
JavaField jf = (JavaField)itField.next();
boolean isStatic;
try {
isStatic = Modifier.isStatic(jf.getModifiers());
} catch (CorruptDataException e) {
out.print("\t <error while getting modifier for field \"");
try {
out.print(jf.getName());
} catch (CorruptDataException d) {
out.print(Exceptions.getCorruptDataExceptionString());
}
out.print("\", " + Exceptions.getCorruptDataExceptionString() + ">");
isStatic = true;
}
if (!isStatic)
{
printNonStaticFieldData(jo, jf, out);
}
}
}
}
out.print("\n");
}
private static void printStaticFieldData(JavaField jf, Output out)
{
printFieldData(null, jf, out, true);
}
private static void printNonStaticFieldData(JavaObject jo, JavaField jf, Output out)
{
printFieldData(jo, jf, out, false);
}
private static void printFieldData(JavaObject jo, JavaField jf, Output out, boolean isStatic)
{
String signature;
out.print("\t ");
try {
String modifierString = Utils.getModifierString(jf.getModifiers());
out.print(modifierString);
} catch (CorruptDataException e) {
out.print(Exceptions.getCorruptDataExceptionString());
}
try {
signature = jf.getSignature();
} catch (CorruptDataException e) {
out.print(Exceptions.getCorruptDataExceptionString());
signature = null;
}
if (null != signature)
{
String name = Utils.getSignatureName(signature);
if (null == name) {
out.print("<unknown>");
} else {
out.print(name);
}
}
out.print(" ");
try {
out.print(jf.getName());
} catch (CorruptDataException e) {
out.print(Exceptions.getCorruptDataExceptionString());
}
if (isStatic || null != jo) {
out.print(" = ");
out.print(Utils.getVal(jo, jf));
}
out.print("\n");
}
public static void printMethods(Iterator methods, Output out)
{
while(methods.hasNext()) {
JavaMethod jMethod = (JavaMethod)methods.next();
try{
out.print("Bytecode range(s): ");
Iterator imageSections = jMethod.getBytecodeSections().iterator();
boolean firstSectionPassed = false;
while (imageSections.hasNext()){
ImageSection is = (ImageSection)imageSections.next();
long baseAddress = is.getBaseAddress().getAddress();
long endAddress = baseAddress + is.getSize();
if (firstSectionPassed) {
out.print(", ");
}
out.print(Long.toHexString(baseAddress) + " -- " +
Long.toHexString(endAddress));
firstSectionPassed = true;
}
out.print(": ");
String signature;
try {
out.print(Utils.getModifierString(jMethod.getModifiers()));
} catch (CorruptDataException e) {
out.print(Exceptions.getCorruptDataExceptionString());
}
try {
signature = jMethod.getSignature();
} catch (CorruptDataException e) {
out.print(Exceptions.getCorruptDataExceptionString());
signature = null;
}
if (null != signature)
{
String name = Utils.getReturnValueName(signature);
if (null == name) {
out.print("<unknown>");
} else {
out.print(name);
}
}
out.print(" ");
out.print(jMethod.getName());
if (null != signature)
{
String name = Utils.getMethodSignatureName(signature);
if (null == name) {
out.print("<unknown>");
} else {
out.print(name);
}
}
out.print("\n");
}catch (CorruptDataException cde){
out.print("N/A (CorruptDataException occurred)");
}
}
}
}