/* Copyright (C) 2004 - 2006 db4objects Inc. http://www.db4o.com This file is part of the db4o open source object database. db4o is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation and as clarified by db4objects' GPL interpretation policy, available at http://www.db4o.com/about/company/legalpolicies/gplinterpretation/ Alternatively you can write to db4objects, Inc., 1900 S Norfolk Street, Suite 350, San Mateo, CA 94403, USA. db4o is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ namespace Db4oTools { using System; using j4o.lang; using j4o.lang.reflect; using j4o.io; using com.db4o; using com.db4o.ext; using com.db4o.foundation; /** * Logger class to log and analyse objects in RAM. *

This class is not part of db4o.jar. It is delivered as * sourcecode in the path ../com/db4o/tools/

*/ public class Logger { private static int MAXIMUM_OBJECTS = 20; /** * opens a database file and logs the content of a class to * standard out. * @param [database filename] [fully qualified classname] */ public static void Main(String[] args) { if (args == null || args.Length == 0) { Console.WriteLine("Usage: java com.db4o.tools.Logger "); } else { if (!new File(args[0]).Exists()) { Console.WriteLine("A database file with the name \'" + args[0] + "\' does not exist."); } else { ExtObjectContainer con1 = null; try { ObjectContainer c1 = Db4o.OpenFile(args[0]); if (c1 == null) { throw new ApplicationException(); } con1 = c1.Ext(); } catch (Exception e) { Console.WriteLine("The database file \'" + args[0] + "\' could not be opened."); return; } if (args.Length > 1) { StoredClass sc1 = con1.StoredClass(args[1]); if (sc1 == null) { Console.WriteLine("There is no stored class with the name \'" + args[1] + "\'."); } else { long[] ids1 = sc1.GetIDs(); for (int i1 = 0; i1 < ids1.Length; i1++) { if (i1 > MAXIMUM_OBJECTS) { break; } Object obj1 = con1.GetByID(ids1[i1]); con1.Activate(obj1, Int32.MaxValue); Log(con1, obj1); } MsgCount(ids1.Length); } } else { ObjectSet set1 = con1.Get(null); int i1 = 0; while (set1.HasNext()) { Object obj1 = set1.Next(); con1.Activate(obj1, Int32.MaxValue); Log(con1, obj1); if (++i1 > MAXIMUM_OBJECTS) { break; } } MsgCount(set1.Size()); } con1.Close(); } } } /** * logs the structure of an object. @param container the {@link ObjectContainer} to be used, or null to log any object. @param Object the object to be analysed. */ public static void Log(ObjectContainer container, Object obj) { if (obj == null) { Log("[NULL]"); } else { Log(j4o.lang.Class.GetClassForObject(obj).GetName()); Log(container, obj, 0, new Collection4()); } } /** * logs the structure of an object. @param Object the object to be analysed. */ public static void Log(Object obj) { ObjectSet objectSet = obj as ObjectSet; if(objectSet != null){ while(objectSet.HasNext()){ Log(objectSet.Next()); } }else{ Log(null, obj); } } /** * logs all objects in the passed ObjectContainer. @param container the {@link ObjectContainer} to be used. */ public static void LogAll(ObjectContainer container) { ObjectSet set1 = container.Get(null); while (set1.HasNext()) { Log(container, set1.Next()); } } /** * limits logging to a maximum depth. @param int the maximum depth. */ public static void SetMaximumDepth(int depth) { maximumDepth = depth; } private static void MsgCount(int count) { Console.WriteLine("\n\nLog complete.\nObjects: " + count); if (count > MAXIMUM_OBJECTS) { Console.WriteLine("Displayed due to setting of " + Class.GetClassForType(typeof(Logger)).GetName() + "#MAXIMUM_OBJECTS: " + MAXIMUM_OBJECTS); } } private static void Log(ObjectContainer a_container, Object a_object, int a_depth, Collection4 a_list) { if (a_list.Contains(a_object) || a_depth > maximumDepth) { return; } Class clazz1 = j4o.lang.Class.GetClassForObject(a_object); for (int i1 = 0; i1 < IGNORE.Length; i1++) { if (clazz1.IsAssignableFrom(IGNORE[i1])) { return; } } if (Platform4.IsSimple(clazz1)) { Log(a_depth + 1, j4o.lang.Class.GetClassForObject(a_object).GetName(), a_object.ToString()); return; } a_list.Add(a_object); Class[] classes1 = GetClassHierarchy(a_object); String spaces1 = ""; for (int i1 = classes1.Length - 1; i1 >= 0; i1--) { spaces1 = spaces1 + sp; String className1 = spaces1; int pos1 = classes1[i1].GetName().LastIndexOf("."); if (pos1 > 0) { className1 += classes1[i1].GetName().Substring(pos1); } else { className1 += classes1[i1].GetName(); } if (classes1[i1] == Class.GetClassForType(typeof(j4o.util.Date))) { String fieldName1 = className1 + ".getTime"; Object obj1 = System.Convert.ToInt64(((j4o.util.Date)a_object).GetTime()); Log(a_container, obj1, Class.GetClassForType(typeof(Int64)), fieldName1, a_depth + 1, -1, a_list); } else { Field[] fields1 = classes1[i1].GetDeclaredFields(); for (int j1 = 0; j1 < fields1.Length; j1++) { Platform4.SetAccessible(fields1[j1]); String fieldName1 = className1 + "." + fields1[j1].GetName(); try { Object obj1 = fields1[j1].Get(a_object); if (j4o.lang.Class.GetClassForObject(obj1).IsArray()) { obj1 = NormalizeNArray(obj1); int len1 = j4o.lang.reflect.JavaArray.GetLength(obj1); for (int k1 = 0; k1 < len1; k1++) { Object element1 = j4o.lang.reflect.JavaArray.Get(obj1, k1); Class arrClass1 = element1 == null ? null : j4o.lang.Class.GetClassForObject(element1); Log(a_container, element1, arrClass1, fieldName1, a_depth + 1, k1, a_list); } } else { Log(a_container, obj1, fields1[j1].GetFieldType(), fieldName1, a_depth + 1, -1, a_list); } } catch (Exception e) { } } } } } private static void Log(ObjectContainer a_container, Object a_object, Class a_Class, String a_fieldName, int a_depth, int a_arrayElement, Collection4 a_list) { if (a_depth > maximumDepth) { return; } String fieldName1 = a_arrayElement > -1 ? a_fieldName + sp + sp + a_arrayElement : a_fieldName; if (a_object != null) { if (a_container == null || a_container.Ext().IsStored(a_object)) { if (a_container == null || a_container.Ext().IsActive(a_object)) { Log(a_depth, fieldName1, ""); Class clazz1 = j4o.lang.Class.GetClassForObject(a_object); bool found1 = false; if (Platform4.IsSimple(clazz1)) { Log(a_depth + 1, j4o.lang.Class.GetClassForObject(a_object).GetName(), a_object.ToString()); found1 = true; } if (!found1) { Log(a_container, a_object, a_depth, a_list); } } else { Log(a_depth, fieldName1, "DEACTIVATED " + j4o.lang.Class.GetClassForObject(a_object).GetName()); } return; } else { Log(a_depth, fieldName1, a_object.ToString()); } } else { Log(a_depth, fieldName1, "[NULL]"); } } private static void Log(String a_msg) { Console.WriteLine(a_msg); } private static void Log(int indent, String a_property, String a_value) { for (int i1 = 0; i1 < indent; i1++) { a_property = sp + sp + a_property; } Log(a_property, a_value); } private static void Log(String a_property, String a_value) { if (a_value == null) a_value = "[NULL]"; Log(a_property + ": " + a_value); } private static void Log(bool a_true) { if (a_true) { Log("true"); } else { Log("false"); } } private static void Log(Exception e, Object obj, String msg) { String l_msg1; if (e != null) { l_msg1 = "!!! " + j4o.lang.Class.GetClassForObject(e).GetName(); String l_exMsg1 = e.Message; if (l_exMsg1 != null) { l_msg1 += sp + l_exMsg1; } } else { l_msg1 = "!!!Exception log"; } if (obj != null) { l_msg1 += " in " + j4o.lang.Class.GetClassForObject(obj).GetName(); } if (msg != null) { l_msg1 += sp + msg; } Log(l_msg1); } private static Class[] GetClassHierarchy(Object a_object) { Class[] classes1 = new Class[]{ j4o.lang.Class.GetClassForObject(a_object) }; return GetClassHierarchy(classes1); } private static Class[] GetClassHierarchy(Class[] a_classes) { Class clazz1 = a_classes[a_classes.Length - 1].GetSuperclass(); if (clazz1.Equals(Class.GetClassForType(typeof(Object)))) { return a_classes; } Class[] classes1 = new Class[a_classes.Length + 1]; System.Array.Copy(a_classes, 0, classes1, 0, a_classes.Length); classes1[a_classes.Length] = clazz1; return GetClassHierarchy(classes1); } private static Object NormalizeNArray(Object a_object) { if (j4o.lang.reflect.JavaArray.GetLength(a_object) > 0) { Object first1 = j4o.lang.reflect.JavaArray.Get(a_object, 0); if (first1 != null && j4o.lang.Class.GetClassForObject(first1).IsArray()) { int[] dim1 = ArrayDimensions(a_object); Object all1 = (Object)new Object[ArrayElementCount(dim1)]; NormalizeNArray1(a_object, all1, 0, dim1, 0); return all1; } } return a_object; } private static int NormalizeNArray1(Object a_object, Object a_all, int a_next, int[] a_dim, int a_index) { if (a_index == a_dim.Length - 1) { for (int i1 = 0; i1 < a_dim[a_index]; i1++) { ((Array)a_all).SetValue(j4o.lang.reflect.JavaArray.Get(a_object, i1), a_next++); } } else { for (int i1 = 0; i1 < a_dim[a_index]; i1++) { a_next = NormalizeNArray1(j4o.lang.reflect.JavaArray.Get(a_object, i1), a_all, a_next, a_dim, a_index + 1); } } return a_next; } private static int[] ArrayDimensions(Object a_object) { int count1 = 0; for (Class clazz1 = j4o.lang.Class.GetClassForObject(a_object); clazz1.IsArray(); clazz1 = clazz1.GetComponentType()) { count1++; } int[] dim1 = new int[count1]; for (int i1 = 0; i1 < count1; i1++) { dim1[i1] = j4o.lang.reflect.JavaArray.GetLength(a_object); a_object = j4o.lang.reflect.JavaArray.Get(a_object, 0); } return dim1; } private static int ArrayElementCount(int[] a_dim) { int elements1 = a_dim[0]; for (int i1 = 1; i1 < a_dim.Length; i1++) { elements1 *= a_dim[i1]; } return elements1; } private static Class[] IGNORE = { Class.GetClassForType(typeof(Class)) }; private static int maximumDepth = Int32.MaxValue; private static String sp = " "; } }