You are viewing a plain text version of this content. The canonical link for it is here.
Posted to kato-commits@incubator.apache.org by mo...@apache.org on 2009/05/07 14:50:35 UTC

svn commit: r772669 [6/7] - in /incubator/kato/trunk: HprofBinaryReaderPOC/ HprofBinaryReaderPOC/.settings/ HprofBinaryReaderPOC/META-INF/ HprofBinaryReaderPOC/bin/ HprofBinaryReaderPOC/bin/org/ HprofBinaryReaderPOC/bin/org/apache/ HprofBinaryReaderPOC...

Added: incubator/kato/trunk/KatoHProfAdapterPOC/src/org/apache/kato/hprof/java/JavaClassImpl.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/KatoHProfAdapterPOC/src/org/apache/kato/hprof/java/JavaClassImpl.java?rev=772669&view=auto
==============================================================================
--- incubator/kato/trunk/KatoHProfAdapterPOC/src/org/apache/kato/hprof/java/JavaClassImpl.java (added)
+++ incubator/kato/trunk/KatoHProfAdapterPOC/src/org/apache/kato/hprof/java/JavaClassImpl.java Thu May  7 14:50:21 2009
@@ -0,0 +1,755 @@
+/*******************************************************************************
+ * 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.hprof.java;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.kato.common.BasicType;
+import org.apache.kato.hprof.IJavaClass;
+import org.apache.kato.hprof.datalayer.ConstantPoolEntry;
+import org.apache.kato.hprof.datalayer.FieldEntry;
+import org.apache.kato.hprof.datalayer.InstanceFieldEntry;
+import org.apache.kato.hprof.datalayer.StaticFieldEntry;
+import org.apache.kato.hprof.image.CorruptDataImpl;
+import org.apache.kato.hprof.image.ImagePointerImpl;
+import org.apache.kato.image.CorruptDataException;
+import org.apache.kato.image.DataUnavailable;
+import org.apache.kato.image.ImagePointer;
+import org.apache.kato.image.MemoryAccessException;
+import org.apache.kato.java.JavaClass;
+import org.apache.kato.java.JavaClassLoader;
+import org.apache.kato.java.JavaField;
+import org.apache.kato.java.JavaObject;
+
+/**
+ * HProf implementation of JavaClass. 
+ * 
+ *
+ */
+public class JavaClassImpl implements JavaClass {
+	IJavaHeapInternal heap;
+	IJavaClass javaClass;
+	
+	/**
+	 * Superclass to static and instance fields.
+	 *
+	 */
+	abstract class JavaFieldImpl implements JavaField {
+		FieldEntry field;
+
+		/**
+		 * Returns the signature of this field.
+		 * Unfortunately, only the fact that a field is an object reference
+		 * is recorded. 
+		 * If we find all objects an object reference field refers to,
+		 * if we take the lowest common subclass then that is the closest to
+		 * the field's actual type. It would be prohibitively expensive to do
+		 * that though.
+		 */
+		@Override
+		public String getSignature() throws CorruptDataException {
+			switch (field.getType()) {
+			case BasicType.OBJECT:
+				return "Ljava/lang/Object;";
+			case BasicType.BOOLEAN:
+				return "Z";
+			case BasicType.CHAR:
+				return "C";
+			case BasicType.FLOAT:
+				return "F";
+			case BasicType.DOUBLE:
+				return "D";
+			case BasicType.BYTE:
+				return "B";
+			case BasicType.SHORT:
+				return "S";
+			case BasicType.INT:
+				return "I";
+			case BasicType.LONG:
+				return "J";
+			default:
+				throw new CorruptDataException(new CorruptDataImpl("Unexpected basic type of " + field.getType()+
+						"encountered."));
+			}
+		}
+
+		@Override
+		public String getName() throws CorruptDataException {
+			return heap.getUTF8StringByID(field.getFieldNameID());
+		}
+		
+		@Override
+		public JavaClass getDeclaringClass() throws CorruptDataException,
+				DataUnavailable {
+					return JavaClassImpl.this;
+				}
+		
+		String getStringFromJavaObject(JavaObject obj) throws CorruptDataException, MemoryAccessException {
+			JavaClass clazz = obj.getJavaClass();
+			JavaObject value=null;
+			int offset=0;
+			int count=0;
+			boolean valueSet = false, offsetSet = false, countSet=false;
+			
+			Iterator iter = clazz.getDeclaredFields();
+			
+			while (iter.hasNext()) {
+				JavaField field = (JavaField) iter.next();
+				String name = field.getName();
+				if("value".equals(name)) {
+					value = (JavaObject) field.get(obj);
+					valueSet = true;
+				} else if ("offset".equals(name)) {
+					offset = field.getInt(obj);
+					offsetSet = true;
+				} else if ("count".equals(name)) {
+					count = field.getInt(obj);
+					countSet = true;
+				}
+				
+			}
+
+			if (valueSet == false || offsetSet == false || countSet == false ) {
+				throw new CorruptDataException(new CorruptDataImpl("Unable to find all String classes fields values"));
+			}
+			char characters[] = new char[count];
+			
+			value.arraycopy(offset, characters, 0, count);
+			
+			return new String(characters);
+		}
+	}
+	
+	class InstanceFieldImpl extends JavaFieldImpl {
+		
+		
+		public InstanceFieldImpl(InstanceFieldEntry field) {
+			this.field = field;
+		}
+		
+		/**
+		 * Returns true if this field can retrieve a value from the passed class.
+		 * 
+		 * @param clazz JavaClassImpl of object to retrieve field from
+		 * @return true if the class is compatible
+		 * 
+		 * @throws CorruptDataException
+		 */
+		private boolean isCompatible(JavaClassImpl clazz) throws CorruptDataException {
+			// checks that this field can be extracted from the passed clazz
+			
+			while(clazz != null) {
+				if (clazz.equals(JavaClassImpl.this)) {
+					return true;
+				}
+				
+				clazz = clazz.getSuperclass();
+			}
+			
+			return false;
+		}
+		
+		/** 
+		 * Returns the offset of this field into a given object.
+		 * 
+		 * @param clazz JavaClassImpl
+		 * @return int offset
+		 * @throws CorruptDataException
+		 */
+		private int getOffset(JavaClassImpl clazz) throws CorruptDataException {
+			// The potential subclasses of this field have to be skipped before
+			// using the stored field offset.			
+			int offset = ((InstanceFieldEntry)field).getOffset();			
+			while ((clazz != null) && !clazz.equals(JavaClassImpl.this)) {
+				offset += clazz.getOffsetSize(); // Or some variant.
+				clazz = clazz.getSuperclass();
+			}
+			return offset;
+		}
+		
+		@Override
+		public Object get(JavaObject obj) throws CorruptDataException,
+				MemoryAccessException {
+			
+			if (! (obj instanceof JavaObjectInstanceImpl)) {
+				throw new IllegalArgumentException("Passed object must be an ordinary object");			
+			}
+			
+			JavaClassImpl clazz = (JavaClassImpl) obj.getJavaClass();
+			
+			if (!isCompatible(clazz)) {
+				throw new IllegalArgumentException("Field " + 
+						JavaClassImpl.this.getName() + "." + 
+						getName() +" not in class hierachy of object 0x"+
+						Long.toHexString(obj.getID().getAddress()));
+			}
+ 			
+			// The potential subclasses of this field have to be skipped before
+			// using the stored field offset. 
+			int offset = getOffset(clazz);
+			
+			JavaObjectInstanceImpl instance = ((JavaObjectInstanceImpl) obj);
+
+			switch(field.getType()) {
+			case BasicType.BOOLEAN:
+				return new Boolean(instance.getBooleanField(offset));
+			case BasicType.BYTE: 
+				return new Byte(instance.getByteField(offset));
+			case BasicType.SHORT: 
+				return new Short(instance.getShortField(offset));
+			case BasicType.CHAR: 
+				return new Character(instance.getCharField(offset));
+			case BasicType.INT: 
+				return new Integer(instance.getIntegerField(offset));
+			case BasicType.LONG: 
+				return new Long(instance.getLongField(offset));
+			case BasicType.FLOAT: 
+				return new Float(instance.getFloatField(offset));
+			case BasicType.DOUBLE: 
+				return new Double(instance.getDoubleField(offset));
+			case BasicType.OBJECT:
+				return JavaClassImpl.this.heap.getObjectByID(instance.getIDField(offset));
+			default:
+				throw new CorruptDataException(new CorruptDataImpl("Invalid field type "
+						+field.getType()));
+			}
+		}
+
+		@Override
+		public boolean getBoolean(JavaObject obj) throws CorruptDataException,
+				MemoryAccessException {
+			JavaObjectInstanceImpl instance = ((JavaObjectInstanceImpl) obj);
+			JavaClassImpl clazz = (JavaClassImpl) obj.getJavaClass();
+			int offset = getOffset(clazz);
+			
+			return instance.getBooleanField(offset);
+		}
+
+		@Override
+		public byte getByte(JavaObject obj) throws CorruptDataException,
+				MemoryAccessException {
+			JavaObjectInstanceImpl instance = ((JavaObjectInstanceImpl) obj);
+			JavaClassImpl clazz = (JavaClassImpl) obj.getJavaClass();
+			int offset = getOffset(clazz);
+			
+			return instance.getByteField(offset);
+		}
+
+		@Override
+		public char getChar(JavaObject obj) throws CorruptDataException,
+				MemoryAccessException {
+			JavaObjectInstanceImpl instance = ((JavaObjectInstanceImpl) obj);
+			JavaClassImpl clazz = (JavaClassImpl) obj.getJavaClass();
+			int offset = getOffset(clazz);
+			
+			return instance.getCharField(offset);
+		}
+
+		@Override
+		public double getDouble(JavaObject obj) throws CorruptDataException,
+				MemoryAccessException {
+			JavaObjectInstanceImpl instance = ((JavaObjectInstanceImpl) obj);
+			JavaClassImpl clazz = (JavaClassImpl) obj.getJavaClass();
+			int offset = getOffset(clazz);
+			
+			return instance.getDoubleField(offset);
+		}
+
+		@Override
+		public float getFloat(JavaObject obj) throws CorruptDataException,
+				MemoryAccessException {
+			JavaObjectInstanceImpl instance = ((JavaObjectInstanceImpl) obj);
+			JavaClassImpl clazz = (JavaClassImpl) obj.getJavaClass();
+			int offset = getOffset(clazz);
+			
+			return instance.getFloatField(offset);
+
+		}
+
+		@Override
+		public int getInt(JavaObject obj) throws CorruptDataException,
+				MemoryAccessException {
+			JavaObjectInstanceImpl instance = ((JavaObjectInstanceImpl) obj);
+			JavaClassImpl clazz = (JavaClassImpl) obj.getJavaClass();
+			int offset = getOffset(clazz);
+			
+			return instance.getIntegerField(offset);
+
+		}
+
+		@Override
+		public long getLong(JavaObject obj) throws CorruptDataException,
+				MemoryAccessException {
+			JavaObjectInstanceImpl instance = ((JavaObjectInstanceImpl) obj);
+			JavaClassImpl clazz = (JavaClassImpl) obj.getJavaClass();
+			int offset = getOffset(clazz);
+			
+			return instance.getLongField(offset);
+
+		}
+
+		@Override
+		public short getShort(JavaObject obj) throws CorruptDataException,
+				MemoryAccessException {
+			JavaObjectInstanceImpl instance = ((JavaObjectInstanceImpl) obj);
+			JavaClassImpl clazz = (JavaClassImpl) obj.getJavaClass();
+			int offset = getOffset(clazz);
+			
+			return instance.getShortField(offset);
+		}
+
+		@Override
+		public String getString(JavaObject obj) throws CorruptDataException,
+				MemoryAccessException {
+			Object fieldObj = get(obj);
+			if (fieldObj == null) {
+				return null;
+			}
+			if (!(fieldObj instanceof JavaObject)) {
+				throw new IllegalArgumentException("Field "+getName()+" not an object");
+			}
+			JavaObject jObject = (JavaObject) fieldObj;
+			
+			if (! "java/lang/String".equals( jObject.getJavaClass().getName() )) {
+				throw new IllegalArgumentException("Field "+getName()+" refers to 0x"+
+						Long.toHexString(jObject.getID().getAddress()) +
+						", which not a string - it's a " + jObject.getJavaClass());
+			}
+			
+			return getStringFromJavaObject(jObject);
+		}
+
+		@Override
+		public int getModifiers() throws CorruptDataException {
+			return 0;
+		}
+		
+	}
+	
+	/**
+	 * Represents a static field.
+	 * Passed JavaObject is always ignored. The actual value is stored
+	 * within the StaticFieldEntry.
+	 * 
+	 */
+	class StaticFieldImpl extends JavaFieldImpl {
+
+		StaticFieldImpl(StaticFieldEntry field) {
+			this.field = field;
+		}
+		
+		/**
+		 * Retrieves the field and returns an Object - primitive types are
+		 * boxed. Other types are implementations of JavaObject, or null.
+		 */
+		@Override
+		public Object get(JavaObject arg0) throws CorruptDataException,
+				MemoryAccessException {
+			StaticFieldEntry field = (StaticFieldEntry) this.field;
+			
+			switch(field.getType()){
+			case BasicType.OBJECT:
+				return heap.getObjectByID(field.getIDField());
+			case BasicType.BOOLEAN:
+				return new Boolean(field.getBooleanField());
+			case BasicType.CHAR:
+				return new Character(field.getCharField());
+			case BasicType.FLOAT:
+				return new Float(field.getFloatField());
+			case BasicType.DOUBLE:
+				return new Double(field.getDoubleField());
+			case BasicType.BYTE:
+				return new Byte(field.getByteField());
+			case BasicType.SHORT:
+				return new Short(field.getShortField());
+			case BasicType.INT:
+				return new Integer(field.getIntegerField());
+			case BasicType.LONG:
+				return new Long(field.getLongField());
+			default:
+				throw new CorruptDataException(new CorruptDataImpl("Unexpected basic type of " + field.getType()+
+						"encountered."));		
+			}
+		}
+
+		@Override
+		public boolean getBoolean(JavaObject arg0) throws CorruptDataException,
+				MemoryAccessException {
+			return ((StaticFieldEntry)field).getBooleanField();
+		}
+
+		@Override
+		public byte getByte(JavaObject arg0) throws CorruptDataException,
+				MemoryAccessException {
+			return ((StaticFieldEntry)field).getByteField();
+		}
+
+		@Override
+		public char getChar(JavaObject arg0) throws CorruptDataException,
+				MemoryAccessException {
+			return ((StaticFieldEntry)field).getCharField();
+		}
+
+		@Override
+		public double getDouble(JavaObject arg0) throws CorruptDataException,
+				MemoryAccessException {
+			return ((StaticFieldEntry)field).getDoubleField();
+		}
+
+		@Override
+		public float getFloat(JavaObject arg0) throws CorruptDataException,
+				MemoryAccessException {
+			return ((StaticFieldEntry)field).getFloatField();
+		}
+
+		@Override
+		public int getInt(JavaObject arg0) throws CorruptDataException,
+				MemoryAccessException {
+			return ((StaticFieldEntry)field).getIntegerField();
+		}
+
+		@Override
+		public long getLong(JavaObject arg0) throws CorruptDataException,
+				MemoryAccessException {
+			return ((StaticFieldEntry)field).getLongField();
+		}
+
+		@Override
+		public short getShort(JavaObject arg0) throws CorruptDataException,
+				MemoryAccessException {
+			return ((StaticFieldEntry)field).getShortField();
+		}
+
+		@Override
+		public String getString(JavaObject arg0) throws CorruptDataException,
+				MemoryAccessException {
+			
+			return getStringFromJavaObject(heap.getObjectByID(((StaticFieldEntry)field).getIDField()));
+		}
+
+		/**
+		 * This field is static - nothing else is known.
+		 */
+		@Override
+		public int getModifiers() throws CorruptDataException {
+			return java.lang.reflect.Modifier.STATIC;
+		}
+	}
+	
+	public JavaClassImpl(IJavaHeapInternal heap, IJavaClass javaClass) {
+		this.heap = heap;
+		this.javaClass = javaClass;
+	}
+	
+	@Override
+	public JavaClassLoader getClassLoader() throws CorruptDataException {
+		return heap.getJavaClassLoaderByID(javaClass.getClassLoaderObjectID());
+	}
+
+	/**
+	 * Get the component type of this class if it is an array class.
+	 * 
+	 * Primitive arrays have primitives as elements, so their component
+	 * type are classes called "int", etc. These classes are faked using 
+	 * JavaPrimitiveClassImpl as they don't exist in hprof dumps. 
+	 *  
+	 * An int[][] array is an array of arrays, hence not primitive.
+	 * 
+	 * The component types are retrieved by name from the JavaClassLoader this
+	 * array class belongs to. 
+	 */
+	@Override
+	public JavaClass getComponentType() throws CorruptDataException {
+		if (!isArray()) {
+			throw new IllegalArgumentException("Class is not an array type");
+		}
+		
+		String name = javaClass.getClassName();
+		
+		if ("boolean[]".equals(name)) {
+			return heap.getPrimitiveClass(BasicType.BOOLEAN);
+		}if ("byte[]".equals(name)) {
+			return heap.getPrimitiveClass(BasicType.BYTE);
+		}if ("short[]".equals(name)) {
+			return heap.getPrimitiveClass(BasicType.SHORT);
+		}if ("char[]".equals(name)) {
+			return heap.getPrimitiveClass(BasicType.CHAR);
+		}if ("int[]".equals(name)) {
+			return heap.getPrimitiveClass(BasicType.INT);
+		}if ("long[]".equals(name)) {
+			return heap.getPrimitiveClass(BasicType.LONG);
+		}if ("float[]".equals(name)) {
+			return heap.getPrimitiveClass(BasicType.FLOAT);
+		}if ("double[]".equals(name)) {
+			return heap.getPrimitiveClass(BasicType.DOUBLE);
+		}
+		
+		String componentName = this.getName().substring(1);
+		
+		/* If the array was "[Ljava/lang/String;"
+		 * Strip it to "java/lang/String"
+		 */
+		if(componentName.charAt(0) == 'L') {
+			componentName = componentName.substring(1,componentName.length()-1);
+		}
+		
+		return getClassLoader().findClass(componentName);
+	}
+
+	@Override
+	public Iterator getConstantPoolReferences() {
+		List cpeList = new LinkedList();
+		
+		
+		ConstantPoolEntry[] cpes = this.javaClass.getConstantPoolEntries();
+
+		for ( ConstantPoolEntry cpe : cpes) {
+			if (cpe.type == BasicType.OBJECT) {
+			//	cpeList.add(heap.getObjectByID(cpe.data));
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * The static and instance fields belonging to this class.
+	 * 
+	 */
+	private ArrayList<JavaField> fields;
+	@Override
+	public Iterator getDeclaredFields() {
+		if (fields == null) {
+			StaticFieldEntry staticFields[] = javaClass.getStaticFields();
+			InstanceFieldEntry instanceFields[] = javaClass.getInstanceFields();
+			
+			fields = new ArrayList<JavaField>(staticFields.length + instanceFields.length);
+			
+			for (StaticFieldEntry f : staticFields) {
+				fields.add(new StaticFieldImpl(f));
+			}
+			
+			for (InstanceFieldEntry f : instanceFields) {
+				fields.add(new InstanceFieldImpl(f));
+			}
+		}
+		
+		return fields.iterator();
+	}
+
+	/** 
+	 * Method information isn't stored within classes.
+	 * 
+	 */
+	@Override
+	public Iterator getDeclaredMethods() {
+		return new LinkedList().iterator();
+	}
+
+	
+	/**
+	 * Wraps up object ID of class as it's ID.
+	 * That should be sufficiently unique.
+	 * 
+	 * @return ImagePointer
+	 */
+	@Override	
+	public ImagePointer getID() {
+		return new ImagePointerImpl(javaClass.getClassObjectID());
+	}
+
+	/**
+	 * Implemented interfaces aren't stored in Hprof.
+	 * The constant pool could be used if the right entries could be targeted, 
+	 * but there is nothing to suggest that that is possible.
+	 */
+	@Override
+	public Iterator getInterfaces() {
+		return new LinkedList().iterator();
+	}
+
+	/**
+	 * There is no modifier information to return
+	 * @return 0
+	 */
+	@Override
+	public int getModifiers() throws CorruptDataException {
+		return 0;
+	}
+
+	/**
+	 * Returns the classes's name. This is stored in hprof with "." and "$" separators,
+	 * the "."s are replaced by "/"s to conform with the API.
+	 * 
+	 * @return String of the class's name.
+	 */
+	@Override
+	public String getName() throws CorruptDataException {
+		String name = javaClass.getClassName();
+		
+		/* Process the array's such that they are of the format:
+		 * [Ljava/lang/Object;
+		 * 
+		 * or 
+		 * [[B
+		 *  
+		 * Primitive arrays are renamed correctly.
+		 */
+		if(name.indexOf('[') != -1) {
+			int depth=0;
+			String prefix = "";
+			for(int n=0; n < name.length(); n++) {
+				if (name.charAt(n) == '[') {
+					prefix+="[";
+				}
+			}
+			
+			// Chop off arrays.
+			name = name.substring(0, name.indexOf('['));
+			
+			if (name.startsWith("boolean")) {
+				name = "Z";
+			} else if (name.startsWith("byte")) {
+				name = "B";
+			} else if (name.startsWith("char")) {
+				name = "C";
+			} else if (name.startsWith("short")) {
+				name = "S";
+			} else if (name.startsWith("int")) {
+				name = "I";
+			} else if (name.startsWith("long")) {
+				name = "J";
+			} else if (name.startsWith("float")) {
+				name = "F";
+			} else if (name.startsWith("double")) {
+				name = "D";
+			} else {
+				name = "L" + name.replace('.', '/') +";";
+			}
+			return prefix+name;
+		}
+		return name.replace('.', '/');
+	}
+
+	/**
+	 * Returns null. There are no java/lang/Class objects referenced
+	 * by the class records. 
+	 */
+	@Override
+	public JavaObject getObject() throws CorruptDataException {
+		return null;
+	}
+
+	/**
+	 * Return the superclass of this class or null.
+	 * 
+	 * @return JavaClassImpl or null
+	 */
+	@Override
+	public JavaClassImpl getSuperclass() throws CorruptDataException {
+		long superClassObjId = javaClass.getSuperClassObjectID();
+		
+		// This is an assumption, but it will be necessary.
+		if (superClassObjId == 0L) {
+			return null;
+		}
+		
+		return heap.getJavaClassByID(superClassObjId);
+	}
+
+	@Override
+	public Iterator getReferences() {
+		// TODO Auto-generated method stub
+		// All object references, constantpool entries, superclass, etc.
+		return null;
+	}
+
+	/**
+	 * Returns true if this is an array.
+	 * 
+	 * @return true if this class is an array type.
+	 */
+	@Override
+	public boolean isArray() throws CorruptDataException {
+		return javaClass.getClassName().indexOf('[') != -1;
+	}
+
+	/**
+	 * @return true if passed object is this JavaClass
+	 */
+	public boolean equals(Object obj) {
+		if (obj == null) {
+			return false;
+		} 
+		
+		if (!(obj instanceof JavaClassImpl)) {
+			return false;
+		}
+		
+		if (obj == this) {
+			return true;
+		}
+		
+		JavaClassImpl clazz = (JavaClassImpl) obj;
+		
+		return clazz.getObjectID() == getObjectID();
+	}
+	
+	/**
+	 * Gets the object ID that uniquely identifies this class on the heap.
+	 * 
+	 * @return long object ID
+	 */
+	long getObjectID() {
+		return javaClass.getClassObjectID();
+	}
+	
+	public String toString() {
+		String name = "<UNSET CLASS NAME>";
+		try {
+			name = this.getName();
+		} catch (CorruptDataException e) {
+			// oh well.
+		}
+		return name+" @ "+ Long.toHexString(javaClass.getClassObjectID());
+	}
+	
+	public int hashCode() {
+		return (int) (javaClass.getClassObjectID() % Integer.MAX_VALUE);
+	}
+	
+	/**
+	 * Return the size of object instances.
+	 * 
+	 * @return int of the object size.
+	 */
+	int getInstanceSize() {
+		return javaClass.getInstanceSize();
+	}
+	
+	/**
+	 * Returns the number of bytes the part of this class takes up in an instance object.
+	 * This is the number of bytes taken up by the fields in this class and none of its
+	 * superclasses.
+	 * This is different from getInstanceSize(), which is the size of an instance of this
+	 * class, including all superclasses.
+	 * 
+	 * @return int fields size
+	 */
+	int getOffsetSize() {
+		return javaClass.getOffsetSize();
+	}
+}

Added: incubator/kato/trunk/KatoHProfAdapterPOC/src/org/apache/kato/hprof/java/JavaClassLoaderImpl.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/KatoHProfAdapterPOC/src/org/apache/kato/hprof/java/JavaClassLoaderImpl.java?rev=772669&view=auto
==============================================================================
--- incubator/kato/trunk/KatoHProfAdapterPOC/src/org/apache/kato/hprof/java/JavaClassLoaderImpl.java (added)
+++ incubator/kato/trunk/KatoHProfAdapterPOC/src/org/apache/kato/hprof/java/JavaClassLoaderImpl.java Thu May  7 14:50:21 2009
@@ -0,0 +1,132 @@
+/*******************************************************************************
+ * 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.hprof.java;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedList;
+
+import org.apache.kato.hprof.HProfView;
+import org.apache.kato.hprof.IJavaClass;
+import org.apache.kato.hprof.IJavaClassLoader;
+import org.apache.kato.hprof.image.CorruptDataImpl;
+import org.apache.kato.hprof.image.ImagePointerImpl;
+import org.apache.kato.image.CorruptDataException;
+import org.apache.kato.java.JavaClassLoader;
+import org.apache.kato.java.JavaObject;
+
+/**
+ * Implements JavaClassLoader.
+ * 
+ *
+ */
+public class JavaClassLoaderImpl implements JavaClassLoader {
+	IJavaClassLoader loader;
+	IJavaHeapInternal heap;
+	
+	public JavaClassLoaderImpl(IJavaHeapInternal heap, IJavaClassLoader loader) {
+		this.loader = loader;
+		this.heap = heap;;
+	}
+	
+	/**
+	 * Returns the JavaClassImpl that has the name passed.
+	 * 
+	 * Iterates through all of the Class object IDs, and retrieves
+	 * the IJavaClasses held in HProfView, so as not to create JavaClasses
+	 * unnecessarily.
+	 */
+	@Override
+	public JavaClassImpl findClass(String className) throws CorruptDataException {
+		if (className == null) {
+			return null;
+		} else if (className.length() == 0) {
+			return null;
+		}
+		
+		Collection<Long> classes = loader.getClasses();
+		
+		for (Long ID : classes) {
+			JavaClassImpl clazz = heap.getJavaClassByID(ID);
+			if (className.equals(clazz.getName())) {
+				return clazz;
+			}
+		}
+		
+		return null;
+	}
+
+	@Override
+	/**
+	 * Returns an empty Iterator, as the HProf format doesn't describe
+	 * how the classes are cached.
+	 * 
+	 * FIXME It may be possible to pull out the classes from the java.lang.ClassLoader.classes Vector 
+	 */
+	public Iterator getCachedClasses() {
+		return new LinkedList().iterator();
+	}
+
+	@Override
+	public Iterator getDefinedClasses() {
+		return new ClassesIterator();
+	}
+
+	/**
+	 * An iterator over the classes loaded by this class loader.
+	 * Wraps the IDs this class loader holds with JavaClassImpls.
+	 * 
+	 * @author monteith
+	 *
+	 */
+	private class ClassesIterator implements Iterator {
+		private Collection<Long> classes = loader.getClasses();
+		private Iterator<Long> iterator = classes.iterator();		
+		@Override
+		public boolean hasNext() {
+			return iterator.hasNext();
+		}
+
+		@Override
+		public Object next() {
+			Long ID = iterator.next();
+			JavaClassImpl clazz = heap.getJavaClassByID(ID);
+
+			if (clazz == null) {
+				return new CorruptDataImpl(new ImagePointerImpl(ID), "Can't match class object ID to a JavaClassImpl.");
+			}
+			
+			return clazz;
+		}
+
+		/**
+		 * Not implemented.
+		 */
+		@Override
+		public void remove() {
+			throw new UnsupportedOperationException("remove() not supported for ClassesIterator");
+		}
+		
+	}
+	
+	/**
+	 * Gets the java/lang/ClassLoader object from the heap.
+	 * 
+	 */
+	@Override
+	public JavaObject getObject() throws CorruptDataException {
+		return heap.getObjectByID(this.loader.getID());
+	}
+
+}

Added: incubator/kato/trunk/KatoHProfAdapterPOC/src/org/apache/kato/hprof/java/JavaHeapImpl.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/KatoHProfAdapterPOC/src/org/apache/kato/hprof/java/JavaHeapImpl.java?rev=772669&view=auto
==============================================================================
--- incubator/kato/trunk/KatoHProfAdapterPOC/src/org/apache/kato/hprof/java/JavaHeapImpl.java (added)
+++ incubator/kato/trunk/KatoHProfAdapterPOC/src/org/apache/kato/hprof/java/JavaHeapImpl.java Thu May  7 14:50:21 2009
@@ -0,0 +1,309 @@
+/*******************************************************************************
+ * 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.hprof.java;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.WeakHashMap;
+
+import org.apache.kato.common.BasicType;
+import org.apache.kato.hprof.HProfView;
+import org.apache.kato.hprof.IJavaClass;
+import org.apache.kato.hprof.IJavaClassLoader;
+import org.apache.kato.hprof.datalayer.IGCInstanceHeapDumpRecord;
+import org.apache.kato.hprof.datalayer.IGCObjectArrayHeapDumpRecord;
+import org.apache.kato.hprof.datalayer.IGCPrimitiveArrayHeapDumpRecord;
+import org.apache.kato.hprof.datalayer.IHProfRecord;
+import org.apache.kato.hprof.datalayer.IHeapDumpHProfRecord;
+import org.apache.kato.hprof.datalayer.IHeapObject;
+import org.apache.kato.java.JavaObject;
+
+
+/**
+ * Contains the contents of the heap - JavaClasses and JavaClassLoaders and object
+ * of all sorts.
+ * 
+ *
+ */
+public class JavaHeapImpl implements IJavaHeapInternal {
+	private JavaRuntimeImpl runtime;
+	private HProfView view=null;
+	long  heapRecordId=0;
+	
+	public JavaHeapImpl(JavaRuntimeImpl runtime,long loc) {
+		if(loc<1) throw new IllegalArgumentException("heap record id ["+loc+"] is less than 1");
+		this.view=runtime.getView();
+		this.heapRecordId=loc;
+		this.runtime = runtime;
+	}
+	
+	@Override
+	public String getName() {
+		
+		return ""+heapRecordId;
+	}
+
+	@Override
+	public Iterator getObjects() {
+		
+		final IHeapDumpHProfRecord record=view.getHeapRecord();
+		
+		if(record==null) return buildEmptyIterator();
+		
+		Iterator iter = new Iterator(){
+			
+			int latestRecord=0;
+			private JavaObject nextObject=null;
+			
+			@Override
+			public boolean hasNext() {
+				
+				if(nextObject!=null) return true;
+				
+				while(true) {
+					IHProfRecord subRecord=record.getSubRecord(latestRecord);
+					if(subRecord==null) {
+						return false;
+					}
+					
+					latestRecord++;
+					
+					// is this an object record?
+					if(subRecord instanceof IGCInstanceHeapDumpRecord) {
+						IGCInstanceHeapDumpRecord instance = (IGCInstanceHeapDumpRecord) subRecord;
+						
+						nextObject = new JavaObjectInstanceImpl(JavaHeapImpl.this, instance);
+						return true;
+					} else if (subRecord instanceof IGCObjectArrayHeapDumpRecord) {
+						IGCObjectArrayHeapDumpRecord objArray = (IGCObjectArrayHeapDumpRecord) subRecord;
+						nextObject = new JavaObjectArrayImpl(JavaHeapImpl.this, objArray);
+						return true;						
+					} else if (subRecord instanceof IGCPrimitiveArrayHeapDumpRecord) {
+						IGCPrimitiveArrayHeapDumpRecord primArray = (IGCPrimitiveArrayHeapDumpRecord) subRecord;
+						nextObject = new JavaPrimitiveArrayImpl(JavaHeapImpl.this, primArray);
+						return true;
+					} 
+				
+					
+				}
+
+			}
+
+			@Override
+			public Object next() {
+				if (hasNext()) {
+					// We'll never get a new object if nextObject is never null...
+					Object returnObject = nextObject;
+					nextObject = null;
+					return returnObject;
+				} else {
+					throw new NoSuchElementException("JavaHeap.getObjects() reached past end of iterator.");
+				}
+			}
+
+			@Override
+			public void remove() {
+				throw new UnsupportedOperationException("JavaHeap.getObject() Iterator.remove() method not supported.");				
+			}};
+		
+		
+
+			iter.hasNext(); // initialize iterator.
+			return iter;
+	}
+
+	private Iterator buildEmptyIterator() {
+		List l=new LinkedList();
+		return l.iterator();
+	}
+
+	@Override
+	public Iterator getSections() {
+		return buildEmptyIterator();
+	}
+
+	/**
+	 * Retrieves an object by it's ID.
+	 * 
+	 * @param ID
+	 * @return
+	 */
+	@Override
+	public JavaObject getObjectByID(Long ID) {
+		if (ID.longValue() == 0L) {
+			return null;
+		}
+		
+		
+		IHeapObject obj = view.getJavaObjectByID(ID);
+
+		if(obj == null) {
+			return null;
+		}
+		
+		if (obj instanceof IGCInstanceHeapDumpRecord) {
+			return new JavaObjectInstanceImpl(this, (IGCInstanceHeapDumpRecord)obj);
+		} else if (obj instanceof IGCObjectArrayHeapDumpRecord) {
+			return new JavaObjectArrayImpl(this, (IGCObjectArrayHeapDumpRecord) obj);
+		} else if (obj instanceof IGCPrimitiveArrayHeapDumpRecord) {
+			return new JavaPrimitiveArrayImpl(this, (IGCPrimitiveArrayHeapDumpRecord) obj);
+		}
+		
+		return null;
+	}
+
+	private WeakHashMap<Long,JavaClassImpl> classCache = new WeakHashMap<Long,JavaClassImpl>();
+
+	/**
+	 * Provides a single point for getting classes.
+	 * All class instantiations should go through here.
+	 * 
+	 * @param ID ID of a class.
+	 * @return JavaClassImpl
+	 */
+	public JavaClassImpl getJavaClassByID(long ID) {
+		JavaClassImpl javaClass = classCache.get(ID);
+		
+		if (javaClass == null) {
+			IJavaClass clazz = view.getJavaClassByID(ID);
+			javaClass = new JavaClassImpl(this, clazz);
+			classCache.put(ID, javaClass);
+		}
+		
+		return javaClass;
+	}
+
+	private JavaClassImpl[] primitiveArrayClasses = new JavaClassImpl[8];
+	
+	/**
+	 * Gets the primitive array of the passed basic type.
+	 * 
+	 * @see org.apache.kato.common.BasicType
+	 * @param type a value from 4 to 11
+	 * @return JavaClassImpl of a primitive array
+	 */
+	public JavaClassImpl getPrimitiveArrayClass(short type) {
+		if (type <4 || type > 11) {
+			throw new IllegalArgumentException("Passed invalid basic type id "+type);
+		}
+		
+		JavaClassImpl clazz = primitiveArrayClasses[type-4];
+		
+		if(clazz == null) {
+			long ID = view.getPrimitiveArrayClass(type).getClassObjectID();
+			clazz = primitiveArrayClasses[type-4] = getJavaClassByID(ID);
+		}
+		
+		return clazz;
+	}
+	
+	private JavaPrimitiveClassImpl[] primitiveClasses = new JavaPrimitiveClassImpl[8];
+	public JavaPrimitiveClassImpl getPrimitiveClass(int type) {
+		if (type < 4 || type > 11) {
+			throw new IllegalArgumentException("Passed invalid basic type id "+type);
+		}
+		
+		JavaPrimitiveClassImpl clazz = primitiveClasses[type-4];
+		
+		if (clazz == null) {
+			String name;
+	
+			switch(type) {
+			case BasicType.BOOLEAN:
+				name = "boolean";
+				break;
+			case BasicType.BYTE:
+				name = "byte";
+				break;
+			case BasicType.SHORT:
+				name = "short";
+				break;
+			case BasicType.CHAR:
+				name = "char";
+				break;
+			case BasicType.INT:
+				name = "int";
+				break;
+			case BasicType.LONG:
+				name = "long";
+				break;
+			case BasicType.FLOAT:
+				name = "float";
+				break;
+			case BasicType.DOUBLE:
+				name = "double";
+				break;
+				default:
+					 name ="<invalid primitive class type "+type+">";
+			}
+			
+			clazz = primitiveClasses[type-4] = new JavaPrimitiveClassImpl(name, type);
+		}
+		
+		return clazz;
+	}
+	
+	/**
+	 * Map from JavaClassLoader IDs to JavaClassLoaders.
+	 */
+	private Map<Long,JavaClassLoaderImpl> javaClassLoaders;
+	
+	/**
+	 * Create a map of JavaClassLoader object ID's to JavaClassLoaderImpl's.
+	 *
+	 * JavaClassLoaders are expected to be sufficiently low in number to warrant
+	 * keeping a definitive collection to avoid duplication by JavaClasses.
+	 */
+	private void createJavaClassLoaders() {
+		if (javaClassLoaders == null) {
+			javaClassLoaders = new HashMap<Long,JavaClassLoaderImpl>();
+			for (IJavaClassLoader loader : view.getJavaClassLoaders()) {
+				javaClassLoaders.put(loader.getID(),new JavaClassLoaderImpl(this, loader));
+			}
+		}
+	}
+	
+	@Override
+	/**
+	 * Returns the java class loaders
+	 * @return 
+	 */
+	public Collection<JavaClassLoaderImpl> getJavaClassLoaders() {
+		createJavaClassLoaders();
+		return javaClassLoaders.values();
+	}
+	/**
+	 * Retrieve a JavaClassLoaderImpl by it's ID.
+	 * Used by JavaClassImpl.
+	 *  
+	 * @param ID
+	 * @return
+	 */
+	@Override
+	public JavaClassLoaderImpl getJavaClassLoaderByID(long ID) {
+		createJavaClassLoaders();
+		return javaClassLoaders.get(ID);
+	}
+
+	@Override
+	public String getUTF8StringByID(long ID) {
+		return view.getUTF8String(ID);
+	}
+	
+}

Added: incubator/kato/trunk/KatoHProfAdapterPOC/src/org/apache/kato/hprof/java/JavaObjectArrayImpl.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/KatoHProfAdapterPOC/src/org/apache/kato/hprof/java/JavaObjectArrayImpl.java?rev=772669&view=auto
==============================================================================
--- incubator/kato/trunk/KatoHProfAdapterPOC/src/org/apache/kato/hprof/java/JavaObjectArrayImpl.java (added)
+++ incubator/kato/trunk/KatoHProfAdapterPOC/src/org/apache/kato/hprof/java/JavaObjectArrayImpl.java Thu May  7 14:50:21 2009
@@ -0,0 +1,168 @@
+/*******************************************************************************
+ * 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.hprof.java;
+
+import java.util.Iterator;
+
+import org.apache.kato.hprof.datalayer.IGCObjectArrayHeapDumpRecord;
+import org.apache.kato.hprof.image.ImagePointerImpl;
+import org.apache.kato.image.CorruptDataException;
+import org.apache.kato.image.DataUnavailable;
+import org.apache.kato.image.ImagePointer;
+import org.apache.kato.image.MemoryAccessException;
+import org.apache.kato.java.JavaClass;
+import org.apache.kato.java.JavaHeap;
+import org.apache.kato.java.JavaObject;
+
+/**
+ * An array of object references.
+ * 
+ * 
+ *
+ */
+public class JavaObjectArrayImpl implements JavaObject {
+	private IJavaHeapInternal heap;
+	private IGCObjectArrayHeapDumpRecord record;
+
+	public JavaObjectArrayImpl(IJavaHeapInternal heap, IGCObjectArrayHeapDumpRecord record) {
+		this.heap = heap;
+		this.record = record;		
+	}
+
+	/**
+	 * Retrieves object IDs from the record on the disk and fills in array
+	 * with JavaObjects by mapping from the IDs to JavaObjects.
+	 * 
+	 */
+	@Override
+	public void arraycopy(int srcStart, Object dst, int dstStart, int length)
+			throws CorruptDataException, MemoryAccessException {
+		if (srcStart < 0 || srcStart > getArraySize()) {
+			throw new IndexOutOfBoundsException("srcStart must be between 0 and " + getArraySize()+", not " + srcStart);
+		}
+		
+		if (srcStart+length > getArraySize()) {
+			throw new IndexOutOfBoundsException("srcStart+length must be <="+getArraySize()+", srcStart=" + srcStart+", length="+length);			
+		}
+		if (dstStart < 0) {
+			throw new IndexOutOfBoundsException("dstStart must be >=0, not " + dstStart);
+		}
+
+		if (dst == null) {
+			throw new IllegalArgumentException("Destination array must not be null");
+		}
+		if (!dst.getClass().isArray()) {
+			throw new IllegalArgumentException("Destination array must be an array, not "+dst.getClass().getName());			
+		}
+		if(dst.getClass().getComponentType() != JavaObject.class) {
+			throw new IllegalArgumentException("Destination array wrong type - must be JavaObject array");
+		}
+		
+		JavaObject[] array = (JavaObject[]) dst;
+		checkArrayBounds(dstStart, array.length, length);
+		
+		for (int i=0; i < length; i++) {
+			array[dstStart+i] = heap.getObjectByID(record.getElement(srcStart+i));
+		}
+	}
+	
+	private static void checkArrayBounds(int arrayStart, int arrayLength, int dataLength) {
+		if ( arrayStart + dataLength > arrayLength) {
+			throw new IndexOutOfBoundsException("Destination array of length "+ arrayLength+" can't" 
+					+ " accomodate array copy with start of "+arrayStart+" and length of "+ dataLength);
+		}
+	}
+	@Override
+	public int getArraySize() throws CorruptDataException {
+		return record.getNumberOfElements();
+	}
+
+	@Override
+	public long getHashcode() throws DataUnavailable, CorruptDataException {
+		// this is probably a bad hash
+		return record.getID(); 
+	}
+
+	@Override
+	public JavaHeap getHeap() throws CorruptDataException, DataUnavailable {
+		return heap;
+	}
+
+	@Override
+	public ImagePointer getID() {
+		return new ImagePointerImpl(record.getID());
+	}
+
+	@Override
+	public JavaClass getJavaClass() throws CorruptDataException {
+		return heap.getJavaClassByID(record.getArrayClassObjectID());
+	}
+
+	@Override
+	public long getPersistentHashcode() throws DataUnavailable,
+			CorruptDataException {
+		throw new DataUnavailable("Persistent hashcode unknown.");	}
+
+	@Override
+	public Iterator getReferences() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public Iterator getSections() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public long getSize() throws CorruptDataException {
+		return 0;
+	}
+
+	@Override
+	public boolean isArray() throws CorruptDataException {
+		return true;
+	}
+	
+	/**
+	 * Compares identity. This object may be created multiple times.
+	 * Uses object ID for comparing identity. 
+	 * We don't check runtime identity.
+	 */
+	@Override
+	public boolean equals(Object obj) {
+		if (obj == null) {
+			return false;
+		}
+		
+		if (!(obj instanceof JavaObjectArrayImpl)) {
+			JavaObjectArrayImpl other = (JavaObjectArrayImpl) obj;
+			
+			if (other.getObjectID() == record.getID()) {
+				return true;
+			}
+		}
+		
+		return false;
+	}
+	
+	/**
+	 * Return object ID of record on disk.
+	 * @return
+	 */
+	long getObjectID() {
+		return record.getID();
+	}
+}

Added: incubator/kato/trunk/KatoHProfAdapterPOC/src/org/apache/kato/hprof/java/JavaObjectInstanceImpl.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/KatoHProfAdapterPOC/src/org/apache/kato/hprof/java/JavaObjectInstanceImpl.java?rev=772669&view=auto
==============================================================================
--- incubator/kato/trunk/KatoHProfAdapterPOC/src/org/apache/kato/hprof/java/JavaObjectInstanceImpl.java (added)
+++ incubator/kato/trunk/KatoHProfAdapterPOC/src/org/apache/kato/hprof/java/JavaObjectInstanceImpl.java Thu May  7 14:50:21 2009
@@ -0,0 +1,238 @@
+/*******************************************************************************
+ * 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.hprof.java;
+
+import java.util.Iterator;
+
+import org.apache.kato.hprof.datalayer.IGCInstanceHeapDumpRecord;
+import org.apache.kato.hprof.image.ImagePointerImpl;
+import org.apache.kato.image.CorruptDataException;
+import org.apache.kato.image.DataUnavailable;
+import org.apache.kato.image.ImagePointer;
+import org.apache.kato.image.MemoryAccessException;
+import org.apache.kato.java.JavaHeap;
+import org.apache.kato.java.JavaObject;
+
+final class JavaObjectInstanceImpl implements JavaObject {
+	/**
+	 * 
+	 */
+	private final IGCInstanceHeapDumpRecord record;
+	private IJavaHeapInternal heap;
+	
+	JavaObjectInstanceImpl(IJavaHeapInternal javaHeapImpl, IGCInstanceHeapDumpRecord record) {
+		this.record = record;
+		this.heap = javaHeapImpl;
+	}
+
+	@Override
+	public void arraycopy(int srcStart, Object dst,
+			int dstStart, int length)
+			throws CorruptDataException,
+			MemoryAccessException {
+		throw new IllegalArgumentException("instance is not an array");		
+	}
+
+	@Override
+	public int getArraySize()
+			throws CorruptDataException {		
+		throw new IllegalArgumentException("instance is not an array");
+	}
+
+	@Override
+	public long getHashcode() throws DataUnavailable,
+			CorruptDataException {		
+		return record.getID();
+	}
+
+	@Override
+	public JavaHeap getHeap()
+			throws CorruptDataException,
+			DataUnavailable {
+		return heap;
+	}
+
+	@Override
+	public ImagePointer getID() {		
+		return new ImagePointerImpl(record.getID());
+	}
+
+	@Override
+	public JavaClassImpl getJavaClass()
+			throws CorruptDataException {
+		return heap.getJavaClassByID(record.getClassObjectID());
+	}
+
+	@Override
+	public long getPersistentHashcode()
+			throws DataUnavailable,
+			CorruptDataException {
+		throw new DataUnavailable("Persistent hashcode unknown.");
+	}
+
+	@Override
+	public Iterator getReferences() {
+		return new Iterator(){			
+			@Override
+			public boolean hasNext() {
+				// TODO Auto-generated method stub
+				return false;
+			}
+
+			@Override
+			public Object next() {
+				// TODO Auto-generated method stub
+				return null;
+			}
+
+			@Override
+			public void remove() {
+				// TODO Auto-generated method stub
+				
+			}};
+	}
+
+	@Override
+	public Iterator getSections() {		
+		return null;
+	}
+
+	@Override
+	public long getSize() throws CorruptDataException {
+		return getJavaClass().getInstanceSize(); 
+	}
+
+	@Override
+	public boolean isArray()
+			throws CorruptDataException {
+		return false;
+	}
+
+	/**
+	 * Retrieve a byte field from this object.
+	 * 
+	 * @param offset into instance values.
+	 * @return byte value
+	 */
+	boolean getBooleanField(int offset) {
+		return record.getBooleanField(offset);
+	}
+	
+	/**
+	 * Retrieve a byte field from this object.
+	 * 
+	 * @param offset into instance values.
+	 * @return byte value
+	 */
+	byte getByteField(int offset) {
+		return record.getByteField(offset);
+	}
+	
+	/**
+	 * Retrieve a char field from this object.
+	 * 
+	 * @param offset into instance values.
+	 * @return char value
+	 */
+	char getCharField(int offset) {
+		return record.getCharField(offset);
+	}
+	
+	/**
+	 * Retrieve a short field from this object.
+	 * 
+	 * @param offset into instance values.
+	 * @return short value
+	 */
+	short getShortField(int offset) {
+		return record.getShortField(offset);
+	}
+	
+	/**
+	 * Retrieve a int field from this object.
+	 * 
+	 * @param offset into instance values.
+	 * @return int value
+	 */
+	int getIntegerField(int offset) {
+		return record.getIntegerField(offset);
+	}
+	
+	/**
+	 * Retrieve a long field from this object.
+	 * 
+	 * @param offset into instance values.
+	 * @return long value
+	 */
+	long getLongField(int offset) {
+		return record.getLongField(offset);
+	}
+	
+	/**
+	 * Retrieve a float field from this object.
+	 * 
+	 * @param offset into instance values.
+	 * @return float value
+	 */
+	float getFloatField(int offset) {
+		return record.getFloatField(offset);
+	}
+	
+	/**
+	 * Retrieve a double field from this object.
+	 * 
+	 * @param offset into instance values.
+	 * @return double value
+	 */
+	double getDoubleField(int offset) {
+		return record.getDoubleField(offset);
+	}
+	
+	/**
+	 * Retrieve an object ID field from this object.
+	 * 
+	 * @param offset into instance values.
+	 * @return long value - an object ID.
+	 */
+	long getIDField(int offset) {
+		return record.getIDField(offset);
+	}
+	
+	/**
+	 * Compares identity. This object may be created multiple times.
+	 * Uses object ID for comparing identity. 
+	 * We don't check runtime identity.
+	 */
+	@Override
+	public boolean equals(Object obj) {
+		if (obj == null) {
+			return false;
+		}
+		
+		if (obj instanceof JavaObjectInstanceImpl) {
+			JavaObjectInstanceImpl other = (JavaObjectInstanceImpl) obj;
+			
+			if (other.getObjectID() == record.getID()) {
+				return true;
+			}
+		}
+		
+		return false;
+	}
+	
+	long getObjectID() {
+		return record.getID();
+	}
+	
+}
\ No newline at end of file

Added: incubator/kato/trunk/KatoHProfAdapterPOC/src/org/apache/kato/hprof/java/JavaPrimitiveArrayImpl.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/KatoHProfAdapterPOC/src/org/apache/kato/hprof/java/JavaPrimitiveArrayImpl.java?rev=772669&view=auto
==============================================================================
--- incubator/kato/trunk/KatoHProfAdapterPOC/src/org/apache/kato/hprof/java/JavaPrimitiveArrayImpl.java (added)
+++ incubator/kato/trunk/KatoHProfAdapterPOC/src/org/apache/kato/hprof/java/JavaPrimitiveArrayImpl.java Thu May  7 14:50:21 2009
@@ -0,0 +1,258 @@
+/*******************************************************************************
+ * 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.hprof.java;
+
+import java.util.Iterator;
+
+import org.apache.kato.common.BasicType;
+import org.apache.kato.hprof.datalayer.IGCPrimitiveArrayHeapDumpRecord;
+import org.apache.kato.hprof.image.CorruptDataImpl;
+import org.apache.kato.hprof.image.ImagePointerImpl;
+import org.apache.kato.image.CorruptDataException;
+import org.apache.kato.image.DataUnavailable;
+import org.apache.kato.image.ImagePointer;
+import org.apache.kato.image.MemoryAccessException;
+import org.apache.kato.java.JavaClass;
+import org.apache.kato.java.JavaHeap;
+import org.apache.kato.java.JavaObject;
+
+public class JavaPrimitiveArrayImpl implements JavaObject {
+	private IJavaHeapInternal heap;
+	private IGCPrimitiveArrayHeapDumpRecord record;
+
+	public JavaPrimitiveArrayImpl(IJavaHeapInternal heap, IGCPrimitiveArrayHeapDumpRecord record) {
+		this.heap = heap;
+		this.record = record;
+	}
+	@Override
+	public void arraycopy(int srcStart, Object dst, int dstStart, int length)
+			throws CorruptDataException, MemoryAccessException {
+		if (srcStart < 0 || srcStart > getArraySize()) {
+			throw new IndexOutOfBoundsException("srcStart must be between 0 and " + getArraySize()+", not " + srcStart);
+		}
+		
+		if (srcStart+length > getArraySize()) {
+			throw new IndexOutOfBoundsException("srcStart+length must be <="+getArraySize()+", srcStart=" + srcStart+", length="+length);			
+		}
+		if (dstStart < 0) {
+			throw new IndexOutOfBoundsException("dstStart must be >=0, not " + dstStart);
+		}
+
+		if (dst == null) {
+			throw new IllegalArgumentException("Destination array must not be null");
+		}
+		if (!dst.getClass().isArray()) {
+			throw new IllegalArgumentException("Destination array must be an array, not "+dst.getClass().getName());			
+		}
+		
+		
+		switch(record.getElementType()) {
+		case BasicType.BOOLEAN:
+		{
+			if(dst.getClass().getComponentType().getName() != "boolean") {
+				throw new IllegalArgumentException("Destination array wrong type - must be boolean");
+			}
+			boolean[] array = (boolean[]) dst;
+			checkArrayBounds(dstStart, array.length, length);
+			
+			for (int i=0; i < length; i++) {
+				array[dstStart+i] = record.getBooleanElement(srcStart+i);
+			}
+			break;
+		}
+		case BasicType.BYTE:
+		{
+			if(dst.getClass().getComponentType().getName() != "byte") {
+				throw new IllegalArgumentException("Destination array wrong type - must be byte");
+			}
+			byte[] array = (byte[]) dst;
+			checkArrayBounds(dstStart, array.length, length);
+			
+			for (int i=0; i < length; i++) {
+				array[dstStart+i] = (byte) record.getByteElement(srcStart+i);
+			}
+			break;
+		}
+		case BasicType.SHORT:
+		{
+			if(dst.getClass().getComponentType().getName() != "short") {
+				throw new IllegalArgumentException("Destination array wrong type - must be short");
+			}
+			short[] array = (short[]) dst;
+			checkArrayBounds(dstStart, array.length, length);
+			
+			for (int i=0; i < length; i++) {
+				array[dstStart+i] =  record.getShortElement(srcStart+i);
+			}
+			break;
+		}
+		case BasicType.CHAR:
+		{
+			if(dst.getClass().getComponentType().getName() != "char") {
+				throw new IllegalArgumentException("Destination array wrong type - must be char");
+			}
+			char[] array = (char[]) dst;
+			checkArrayBounds(dstStart, array.length, length);
+			
+			for (int i=0; i < length; i++) {
+				array[dstStart+i] =  record.getCharElement(srcStart+i);
+			}
+			break;
+		}
+		case BasicType.INT:
+		{
+			if(dst.getClass().getComponentType().getName() != "int") {
+				throw new IllegalArgumentException("Destination array wrong type - must be int");
+			}
+			int[] array = (int[]) dst;
+			checkArrayBounds(dstStart, array.length, length);
+			
+			for (int i=0; i < length; i++) {
+				array[dstStart+i] =  record.getIntElement(srcStart+i);
+			}
+			break;
+		}
+		case BasicType.LONG:
+		{
+			if(dst.getClass().getComponentType().getName() != "long") {
+				throw new IllegalArgumentException("Destination array wrong type - must be long");
+			}
+			long[] array = (long[]) dst;
+			checkArrayBounds(dstStart, array.length, length);
+			
+			for (int i=0; i < length; i++) {
+				array[dstStart+i] =  record.getLongElement(srcStart+i);
+			}
+			break;
+		}
+		case BasicType.FLOAT:
+		{
+			if(dst.getClass().getComponentType().getName() != "float") {
+				throw new IllegalArgumentException("Destination array wrong type - must be float");
+			}
+			float[] array = (float[]) dst;
+			checkArrayBounds(dstStart, array.length, length);
+			
+			for (int i=0; i < length; i++) {
+				array[dstStart+i] =  record.getFloatElement(srcStart+i);
+			}
+			break;
+		}
+		case BasicType.DOUBLE:
+		{
+			if(dst.getClass().getComponentType().getName() != "double") {
+				throw new IllegalArgumentException("Destination array wrong type - must be double");
+			}
+			double[] array = (double[]) dst;
+			checkArrayBounds(dstStart, array.length, length);
+			
+			for (int i=0; i < length; i++) {
+				array[dstStart+i] =  record.getDoubleElement(srcStart+i);
+			}
+			break;
+		}
+		default:
+			throw new CorruptDataException(new CorruptDataImpl("Primitive array has invalid type of "+record.getElementType()));
+		}
+	}
+
+	private static void checkArrayBounds(int arrayStart, int arrayLength, int dataLength) {
+		if ( arrayStart + dataLength > arrayLength) {
+			throw new IndexOutOfBoundsException("Destination array of length "+ arrayLength+" can't" 
+					+ " accomodate array copy with start of "+arrayStart+" and length of "+ dataLength);
+		}
+	}
+	@Override
+	public int getArraySize() throws CorruptDataException {
+		return record.getNumberOfElements();
+	}
+
+	@Override
+	public long getHashcode() throws DataUnavailable, CorruptDataException {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	@Override
+	public JavaHeap getHeap() throws CorruptDataException, DataUnavailable {
+		return heap;
+	}
+
+	@Override
+	public ImagePointer getID() {
+		return new ImagePointerImpl(record.getID());
+	}
+
+	@Override
+	public JavaClass getJavaClass() throws CorruptDataException {
+		return heap.getPrimitiveArrayClass(record.getElementType());
+	}
+
+	@Override
+	public long getPersistentHashcode() throws DataUnavailable,
+			CorruptDataException {
+		throw new DataUnavailable("Persistent hashcode unknown.");	}
+
+	@Override
+	public Iterator getReferences() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public Iterator getSections() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public long getSize() throws CorruptDataException {
+		return 0;
+	}
+
+	@Override
+	public boolean isArray() throws CorruptDataException {
+		return true;
+	}
+
+	/**
+	 * Compares identity. This object may be created multiple times.
+	 * Uses object ID for comparing identity. 
+	 * We don't check runtime identity.
+	 */
+	@Override
+	public boolean equals(Object obj) {
+		if (obj == null) {
+			return false;
+		}
+		
+		if (!(obj instanceof JavaPrimitiveArrayImpl)) {
+			JavaPrimitiveArrayImpl other = (JavaPrimitiveArrayImpl) obj;
+			
+			if (other.getObjectID() == record.getID()) {
+				return true;
+			}
+		}
+		
+		return false;
+	}
+	
+	/**
+	 * Return object ID of record on disk.
+	 * @return
+	 */
+	long getObjectID() {
+		return record.getID();
+	}
+}

Added: incubator/kato/trunk/KatoHProfAdapterPOC/src/org/apache/kato/hprof/java/JavaPrimitiveClassImpl.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/KatoHProfAdapterPOC/src/org/apache/kato/hprof/java/JavaPrimitiveClassImpl.java?rev=772669&view=auto
==============================================================================
--- incubator/kato/trunk/KatoHProfAdapterPOC/src/org/apache/kato/hprof/java/JavaPrimitiveClassImpl.java (added)
+++ incubator/kato/trunk/KatoHProfAdapterPOC/src/org/apache/kato/hprof/java/JavaPrimitiveClassImpl.java Thu May  7 14:50:21 2009
@@ -0,0 +1,108 @@
+/*******************************************************************************
+ * 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.hprof.java;
+
+import java.util.Iterator;
+import java.util.Vector;
+
+import org.apache.kato.hprof.image.ImagePointerImpl;
+import org.apache.kato.image.CorruptDataException;
+import org.apache.kato.image.ImagePointer;
+import org.apache.kato.java.JavaClass;
+import org.apache.kato.java.JavaClassLoader;
+import org.apache.kato.java.JavaObject;
+
+/**
+ * There aren't any primitive types in hprof dumps.
+ * We have to fake them.
+ * 
+ *
+ */
+public class JavaPrimitiveClassImpl implements JavaClass {
+	private String name;
+	private int id;
+
+	public JavaPrimitiveClassImpl(String name, int id) {
+		this.name = name;
+		this.id = id;
+	}
+	
+	@Override
+	public JavaClassLoader getClassLoader() throws CorruptDataException {
+		// TODO This should probably exist.
+		return null;
+	}
+
+	@Override
+	public JavaClass getComponentType() throws CorruptDataException {
+		return null;
+	}
+
+	@Override
+	public Iterator getConstantPoolReferences() {
+		return new Vector(0).iterator();
+	}
+
+	@Override
+	public Iterator getDeclaredFields() {
+		return new Vector(0).iterator();
+	}
+
+	@Override
+	public Iterator getDeclaredMethods() {
+		return new Vector(0).iterator();
+	}
+
+	
+	@Override
+	public ImagePointer getID() {
+		// Use basic type id as the id.
+		return new ImagePointerImpl(id);
+	}
+
+	@Override
+	public Iterator getInterfaces() {
+		return new Vector(0).iterator();
+	}
+
+	@Override
+	public int getModifiers() throws CorruptDataException {
+		return 0;
+	}
+
+	@Override
+	public String getName() throws CorruptDataException {
+		return name;
+	}
+
+	@Override
+	public JavaObject getObject() throws CorruptDataException {
+		return null;
+	}
+
+	@Override
+	public Iterator getReferences() {
+		return new Vector(0).iterator();
+	}
+
+	@Override
+	public JavaClass getSuperclass() throws CorruptDataException {
+		return null;		
+	}
+
+	@Override
+	public boolean isArray() throws CorruptDataException {
+		return false;
+	}
+}

Added: incubator/kato/trunk/KatoHProfAdapterPOC/src/org/apache/kato/hprof/java/JavaRuntimeImpl.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/KatoHProfAdapterPOC/src/org/apache/kato/hprof/java/JavaRuntimeImpl.java?rev=772669&view=auto
==============================================================================
--- incubator/kato/trunk/KatoHProfAdapterPOC/src/org/apache/kato/hprof/java/JavaRuntimeImpl.java (added)
+++ incubator/kato/trunk/KatoHProfAdapterPOC/src/org/apache/kato/hprof/java/JavaRuntimeImpl.java Thu May  7 14:50:21 2009
@@ -0,0 +1,160 @@
+/*******************************************************************************
+ * 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.hprof.java;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+import org.apache.kato.common.BasicType;
+import org.apache.kato.common.IViewMonitor;
+import org.apache.kato.hprof.HProfView;
+import org.apache.kato.hprof.IJavaClass;
+import org.apache.kato.hprof.IJavaClassLoader;
+import org.apache.kato.hprof.datalayer.HProfFile;
+import org.apache.kato.hprof.datalayer.IGCInstanceHeapDumpRecord;
+import org.apache.kato.hprof.datalayer.IGCObjectArrayHeapDumpRecord;
+import org.apache.kato.hprof.datalayer.IGCPrimitiveArrayHeapDumpRecord;
+import org.apache.kato.hprof.datalayer.IHeapObject;
+import org.apache.kato.image.CorruptDataException;
+import org.apache.kato.image.DataUnavailable;
+import org.apache.kato.image.ImagePointer;
+import org.apache.kato.image.MemoryAccessException;
+import org.apache.kato.java.JavaHeap;
+import org.apache.kato.java.JavaObject;
+import org.apache.kato.java.JavaRuntime;
+import org.apache.kato.java.JavaVMInitArgs;
+
+public class JavaRuntimeImpl implements JavaRuntime {
+
+	private HProfView view=null;
+	public JavaRuntimeImpl(HProfFile file) {
+		this.view=new HProfView(file);
+		view.open(new IViewMonitor(){
+
+			@Override
+			public void error(IOException e) {
+				// TODO Auto-generated method stub
+				
+			}});
+		heap = new JavaHeapImpl(this, view.getHeapRecordLocation());
+	}
+
+	/**
+	 * Return the HProfView this JavaRuntime is based on.
+	 * 
+	 * @return HProfView.
+	 */
+	HProfView getView() {
+		return view;
+	}
+	
+	@Override
+	public Iterator getCompiledMethods() {
+		
+		
+		List l=new LinkedList();
+		return l.iterator();
+	}
+
+	@Override
+	public Iterator getHeapRoots() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	private JavaHeapImpl heap;
+	
+	@Override
+	public Iterator getHeaps() {
+		List<JavaHeapImpl> l=new LinkedList<JavaHeapImpl>();
+		l.add(heap);
+		return l.iterator();
+	}
+
+	
+	
+	/**
+	 * Retrieves all of the JavaClassLoaders owned by this JavaRuntime.
+	 * 
+	 * 
+	 * @return Iterator<JavaClassLoaderImpl>
+	 */
+	@Override	
+	public Iterator<JavaClassLoaderImpl> getJavaClassLoaders() {
+		return heap.getJavaClassLoaders().iterator();
+	}
+
+	
+	@Override
+	public ImagePointer getJavaVM() throws CorruptDataException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public JavaVMInitArgs getJavaVMInitArgs() throws DataUnavailable,
+			CorruptDataException {
+			throw new DataUnavailable();
+			
+	}
+
+	@Override
+	public Iterator getMonitors() {
+		
+		return null;
+	}
+
+	@Override
+	public JavaObject getObjectAtAddress(ImagePointer address)
+			throws CorruptDataException, IllegalArgumentException,
+			MemoryAccessException, DataUnavailable {
+		return heap.getObjectByID(address.getAddress());
+	}
+
+	@Override
+	public Iterator getThreads() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public Object getTraceBuffer(String bufferName, boolean formatted)
+			throws CorruptDataException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public String getFullVersion() throws CorruptDataException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public String getVersion() throws CorruptDataException {
+		// TODO Auto-generated method stub
+		return null;
+	}
+	
+
+
+	JavaHeap getHeap() {
+		return heap;
+	}
+}

Added: incubator/kato/trunk/KatoHProfAdapterPOC/testsrc/data/empty.hprof
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/KatoHProfAdapterPOC/testsrc/data/empty.hprof?rev=772669&view=auto
==============================================================================
    (empty)

Added: incubator/kato/trunk/KatoHProfAdapterPOC/testsrc/data/headeronly.hprof
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/KatoHProfAdapterPOC/testsrc/data/headeronly.hprof?rev=772669&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/kato/trunk/KatoHProfAdapterPOC/testsrc/data/headeronly.hprof
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/kato/trunk/KatoHProfAdapterPOC/testsrc/data/minimal.hprof
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/KatoHProfAdapterPOC/testsrc/data/minimal.hprof?rev=772669&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/kato/trunk/KatoHProfAdapterPOC/testsrc/data/minimal.hprof
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/kato/trunk/KatoHProfAdapterPOC/testsrc/data/populated.hprof
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/KatoHProfAdapterPOC/testsrc/data/populated.hprof?rev=772669&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/kato/trunk/KatoHProfAdapterPOC/testsrc/data/populated.hprof
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/kato/trunk/KatoHProfAdapterPOC/testsrc/org/apache/kato/hprof/java/GCInstanceHeapDumpRecordTest.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/KatoHProfAdapterPOC/testsrc/org/apache/kato/hprof/java/GCInstanceHeapDumpRecordTest.java?rev=772669&view=auto
==============================================================================
--- incubator/kato/trunk/KatoHProfAdapterPOC/testsrc/org/apache/kato/hprof/java/GCInstanceHeapDumpRecordTest.java (added)
+++ incubator/kato/trunk/KatoHProfAdapterPOC/testsrc/org/apache/kato/hprof/java/GCInstanceHeapDumpRecordTest.java Thu May  7 14:50:21 2009
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * 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.hprof.java;
+
+import org.apache.kato.hprof.datalayer.IGCInstanceHeapDumpRecord;
+
+public class GCInstanceHeapDumpRecordTest implements IGCInstanceHeapDumpRecord{
+	@Override
+	public boolean getBooleanField(int offset) {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	@Override
+	public byte getByteField(int offset) {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	@Override
+	public char getCharField(int offset) {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	@Override
+	public long getClassObjectID() {
+		return 12;
+	}
+
+	@Override
+	public double getDoubleField(int offset) {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	@Override
+	public float getFloatField(int offset) {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	@Override
+	public long getIDField(int offset) {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	@Override
+	public int getIntegerField(int offset) {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	@Override
+	public long getLongField(int offset) {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	@Override
+	public short getShortField(int offset) {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	@Override
+	public long getID() {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	@Override
+	public int getStackTraceNumber() {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+	
+}
\ No newline at end of file

Added: incubator/kato/trunk/KatoHProfAdapterPOC/testsrc/org/apache/kato/hprof/java/JavaHeapImplTest.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/KatoHProfAdapterPOC/testsrc/org/apache/kato/hprof/java/JavaHeapImplTest.java?rev=772669&view=auto
==============================================================================
--- incubator/kato/trunk/KatoHProfAdapterPOC/testsrc/org/apache/kato/hprof/java/JavaHeapImplTest.java (added)
+++ incubator/kato/trunk/KatoHProfAdapterPOC/testsrc/org/apache/kato/hprof/java/JavaHeapImplTest.java Thu May  7 14:50:21 2009
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * 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.hprof.java;
+
+import java.util.Collection;
+import java.util.Iterator;
+
+import org.apache.kato.java.JavaObject;
+
+public class JavaHeapImplTest implements IJavaHeapInternal {
+
+	@Override
+	public JavaClassImpl getJavaClassByID(long arrayClassObjectID) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public JavaClassLoaderImpl getJavaClassLoaderByID(long classLoaderObjectID) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public Collection<JavaClassLoaderImpl> getJavaClassLoaders() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public JavaObject getObjectByID(Long element) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public JavaClassImpl getPrimitiveArrayClass(short elementType) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public JavaPrimitiveClassImpl getPrimitiveClass(int l) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public String getUTF8StringByID(long fieldNameID) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public String getName() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public Iterator getObjects() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public Iterator getSections() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+}

Added: incubator/kato/trunk/KatoHProfAdapterPOC/testsrc/org/apache/kato/hprof/java/JavaObjectInstanceImplTest.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/KatoHProfAdapterPOC/testsrc/org/apache/kato/hprof/java/JavaObjectInstanceImplTest.java?rev=772669&view=auto
==============================================================================
--- incubator/kato/trunk/KatoHProfAdapterPOC/testsrc/org/apache/kato/hprof/java/JavaObjectInstanceImplTest.java (added)
+++ incubator/kato/trunk/KatoHProfAdapterPOC/testsrc/org/apache/kato/hprof/java/JavaObjectInstanceImplTest.java Thu May  7 14:50:21 2009
@@ -0,0 +1,60 @@
+package org.apache.kato.hprof.java;
+
+
+/*******************************************************************************
+ * 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.
+ ******************************************************************************/
+import junit.framework.TestCase;
+
+public class JavaObjectInstanceImplTest extends TestCase {
+	JavaObjectInstanceImpl instance;
+	IJavaHeapInternal heap;
+	GCInstanceHeapDumpRecordTest gcInstance;
+	
+	public void setUp() {
+		heap = new JavaHeapImplTest();
+		gcInstance =  new GCInstanceHeapDumpRecordTest();
+		instance = new JavaObjectInstanceImpl(heap, gcInstance);
+	}
+	
+	public void testGetHeap() throws Exception {
+		assertEquals("JavaHeaps don't match.", heap, instance.getHeap());
+	}
+	
+	public void testGetID() throws Exception {
+		assertEquals("ID incorrectly retrieved", gcInstance.getID(), instance.getID().getAddress());
+	}
+	
+	public void testGetObjectID() throws Exception {
+		assertEquals("ID incorrectly retrieved", gcInstance.getID(), instance.getObjectID());
+	}
+	public void testEqualsNull() throws Exception {
+		assertFalse("equals(null) should be false.",instance.equals(null));
+	}
+	
+	public void testEqualsWrongType() throws Exception {
+		assertFalse("equals(String) should be false.", instance.equals("Completely wrong type"));
+	}
+	
+	public void testEquals() throws Exception {
+		assertTrue("instance.equals(instance) should be true.", instance.equals(instance));
+	}
+	
+	public void testIsArray() throws Exception {
+		assertFalse("instance.isArray() should be false", instance.isArray());
+	}
+	
+	public void testGetArraySize() throws Exception {
+		//assert
+	}
+}

Added: incubator/kato/trunk/KatoHProfAdapterPOC/testsrc/test/apache/kato/hprof/AllTests.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/KatoHProfAdapterPOC/testsrc/test/apache/kato/hprof/AllTests.java?rev=772669&view=auto
==============================================================================
--- incubator/kato/trunk/KatoHProfAdapterPOC/testsrc/test/apache/kato/hprof/AllTests.java (added)
+++ incubator/kato/trunk/KatoHProfAdapterPOC/testsrc/test/apache/kato/hprof/AllTests.java Thu May  7 14:50:21 2009
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * 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 test.apache.kato.hprof;
+
+import test.apache.kato.hprof.image.TestImage;
+import test.apache.kato.hprof.image.TestImageAddressSpace;
+import test.apache.kato.hprof.image.TestImageFactory;
+import test.apache.kato.hprof.image.TestImageProcess;
+import test.apache.kato.hprof.java.TestJavaRuntime;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class AllTests {
+
+	public static Test suite() {
+		TestSuite suite = new TestSuite("Test for test.apache.kato.hprof");
+		//$JUnit-BEGIN$
+		suite.addTestSuite(TestImageProcess.class);
+		suite.addTestSuite(TestImageFactory.class);
+		suite.addTestSuite(TestImageAddressSpace.class);
+		suite.addTestSuite(TestImage.class);
+		
+		suite.addTestSuite(TestJavaRuntime.class);
+		
+		//$JUnit-END$
+		return suite;
+	}
+
+}

Added: incubator/kato/trunk/KatoHProfAdapterPOC/testsrc/test/apache/kato/hprof/TestJavaHeap.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/KatoHProfAdapterPOC/testsrc/test/apache/kato/hprof/TestJavaHeap.java?rev=772669&view=auto
==============================================================================
--- incubator/kato/trunk/KatoHProfAdapterPOC/testsrc/test/apache/kato/hprof/TestJavaHeap.java (added)
+++ incubator/kato/trunk/KatoHProfAdapterPOC/testsrc/test/apache/kato/hprof/TestJavaHeap.java Thu May  7 14:50:21 2009
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * 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 test.apache.kato.hprof;
+
+import java.io.IOException;
+
+import org.apache.kato.hprof.HProfView;
+import org.apache.kato.hprof.java.JavaHeapImpl;
+
+import test.apache.kato.hprof.image.AbstractHProfTestCase;
+
+public class TestJavaHeap extends AbstractHProfTestCase {
+
+	public void testNullConstructor() {
+		
+		try {
+		JavaHeapImpl impl=new JavaHeapImpl(null,0);
+		fail("expected illegal argument exception");
+		}
+		catch(IllegalArgumentException iae) {
+			;
+		}
+	}
+	public void testBadHeapRecordIDConstructor() throws IOException {
+		
+		
+		HProfView view=getMinimalHProfView();
+		
+		try {
+		JavaHeapImpl impl=new JavaHeapImpl(view,0);
+		fail("expected illegal argument exception");
+		}
+		catch(IllegalArgumentException iae) {
+			;
+		}
+	}
+}

Added: incubator/kato/trunk/KatoHProfAdapterPOC/testsrc/test/apache/kato/hprof/image/AbstractHProfTestCase.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/KatoHProfAdapterPOC/testsrc/test/apache/kato/hprof/image/AbstractHProfTestCase.java?rev=772669&view=auto
==============================================================================
--- incubator/kato/trunk/KatoHProfAdapterPOC/testsrc/test/apache/kato/hprof/image/AbstractHProfTestCase.java (added)
+++ incubator/kato/trunk/KatoHProfAdapterPOC/testsrc/test/apache/kato/hprof/image/AbstractHProfTestCase.java Thu May  7 14:50:21 2009
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * 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 test.apache.kato.hprof.image;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.util.Iterator;
+
+import junit.framework.TestCase;
+
+import org.apache.kato.hprof.HProfView;
+import org.apache.kato.hprof.datalayer.HProfFactory;
+import org.apache.kato.hprof.datalayer.HProfFile;
+import org.apache.kato.hprof.image.ImageFactoryImpl;
+import org.apache.kato.image.Image;
+import org.apache.kato.image.ImageAddressSpace;
+import org.apache.kato.image.ImageProcess;
+import org.apache.kato.java.JavaHeap;
+import org.apache.kato.java.JavaRuntime;
+
+public abstract class AbstractHProfTestCase extends TestCase {
+
+	 
+	public  File getFile(String fileName) {
+		URL u=getClass().getResource(fileName);
+		String path=u.getPath();
+		File realFile=new File(path);
+		return realFile;
+	}
+
+	protected File getEmptyHProfFile() {
+		File realFile = getFile("/data/empty.hprof");
+		return realFile;
+	}
+
+	protected File getHeaderOnlyHProfFile() {
+		File realFile = getFile("/data/headeronly.hprof");
+		return realFile;
+	}
+	protected File getPopulatedHProfFile() {
+		File realFile = getFile("/data/populated.hprof");
+		return realFile;
+	}
+	protected File getMinimalHProfFile() {
+		File realFile = getFile("/data/minimal.hprof");
+		return realFile;
+	}
+
+	public HProfView getMinimalHProfView() throws IOException {
+		File m=getMinimalHProfFile();
+		HProfFile hprofFile=HProfFactory.createReader(m);
+		hprofFile.open();
+		return new HProfView(hprofFile);
+	
+	}
+	public Image getMinimalImage() throws IOException {
+		ImageFactoryImpl factory=new ImageFactoryImpl();
+		return factory.getImage(getMinimalHProfFile());
+		
+	}
+	public Image getPopulatedImage() throws IOException {
+		ImageFactoryImpl factory=new ImageFactoryImpl();
+		return factory.getImage(getPopulatedHProfFile());
+		
+	}
+	protected ImageAddressSpace getFirstAddressSpace() throws IOException {
+		Image minimal=getMinimalImage();
+		Iterator i=minimal.getAddressSpaces();
+		Object o=i.next();
+		ImageAddressSpace space=(ImageAddressSpace) o;
+		return space;
+	}
+
+	protected ImageProcess getCurrentProcess() throws IOException {
+		
+		ImageAddressSpace space=getFirstAddressSpace();
+		return space.getCurrentProcess();
+		
+	}
+
+	protected JavaRuntime getJavaRuntime() throws IOException {
+		
+		return (JavaRuntime) getCurrentProcess().getRuntimes().next(); 
+	}
+protected JavaRuntime getPopulatedJavaRuntime() throws IOException {
+		
+		return (JavaRuntime) getCurrentProcess().getRuntimes().next(); 
+	}
+
+protected JavaHeap getPopulatedJavaHeap() throws IOException {
+	Image populated=getPopulatedImage();
+	Iterator i=populated.getAddressSpaces();
+	Object o=i.next();
+	ImageAddressSpace space=(ImageAddressSpace) o;
+	ImageProcess process=space.getCurrentProcess();
+	JavaRuntime rt=(JavaRuntime) process.getRuntimes().next();
+	return (JavaHeap) rt.getHeaps().next();
+	 
+}
+
+	
+}