001 /* 002 Copyright (C) 2001 Renaud Pawlak 003 004 This program is free software; you can redistribute it and/or modify 005 it under the terms of the GNU Lesser General Public License as 006 published by the Free Software Foundation; either version 2 of the 007 License, or (at your option) any later version. 008 009 This program is distributed in the hope that it will be useful, 010 but WITHOUT ANY WARRANTY; without even the implied warranty of 011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 012 GNU Lesser General Public License for more details. 013 014 You should have received a copy of the GNU Lesser General Public License 015 along with this program; if not, write to the Free Software 016 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ 017 018 package org.objectweb.jac.aspects.tracing; 019 020 import org.objectweb.jac.core.*; 021 import java.util.*; 022 import org.objectweb.jac.core.rtti.ClassRepository; 023 024 /** 025 * This class is able to record a set of methods call and replay them. 026 */ 027 028 public class Recorder { 029 030 static Recorder recorder; 031 Vector calls = new Vector(); 032 Vector newObjectsClasses = new Vector(); 033 Hashtable newObjectsIndexes = new Hashtable(); 034 boolean recording = false; 035 int newObjectsCount = 0; 036 037 public void printRecordState() { 038 Iterator it = calls.iterator(); 039 while( it.hasNext() ) { 040 Object[] call = (Object[])it.next(); 041 System.out.println("- "+call[0]+"."+call[1]+ 042 Arrays.asList((Object[])call[2])); 043 } 044 } 045 046 public static Recorder get() { 047 return recorder; 048 } 049 050 public boolean isRecording() { 051 return recording; 052 } 053 054 public void start() { 055 calls.clear(); 056 newObjectsClasses.clear(); 057 newObjectsIndexes.clear(); 058 newObjectsCount = 0; 059 recording = true; 060 } 061 062 public void stop() { 063 recording = false; 064 } 065 066 public Vector getCalls() { 067 return calls; 068 } 069 070 public Vector getNewObjectsClasses() { 071 return newObjectsClasses; 072 } 073 074 public void replay( Vector newObjectsClasses, Vector calls ) { 075 if( recording ) return; 076 // create the objects that have been instanciated 077 // during the record 078 Vector createdObjects = new Vector(); 079 Iterator it = newObjectsClasses.iterator(); 080 while( it.hasNext() ) { 081 Class newObjectClass = (Class)it.next(); 082 try { 083 Object o = newObjectClass.newInstance(); 084 createdObjects.add(o); 085 System.out.println("REPLAY: creating new object "+o); 086 } catch( Exception e ) { 087 System.out.println("FATAL ERROR: replay failed!!"); 088 e.printStackTrace(); 089 return; 090 } 091 } 092 // invoke the same method that have been called during 093 // the record 094 it = calls.iterator(); 095 while( it.hasNext() ) { 096 Object[] call = (Object[])it.next(); 097 Wrappee o; 098 if( call[0] instanceof Integer ) { 099 // resolve a created object 100 o = (Wrappee)createdObjects.get( ((Integer)call[0]).intValue() ); 101 } else { 102 // resolve a pre-exisisting object 103 o = (Wrappee)NameRepository.get().getObject( (String)call[0] ); 104 } 105 System.out.println("REPLAY: calling recorded "+o+"."+ 106 (String)call[1]+Arrays.asList((Object[])call[2])); 107 ClassRepository.get().getClass(o).getMethod((String)call[1]).invoke( 108 o, (Object[])call[2] ); 109 } 110 } 111 112 public void recordMethodCall(Object o, String methodName, Object[] args) { 113 if( isNewObject(o) ) { 114 calls.add( new Object[] { newObjectsIndexes.get(o), 115 methodName, args } ); 116 } else { 117 calls.add( new Object[] { NameRepository.get().getName(o), 118 methodName, args } ); 119 } 120 } 121 122 public void recordNewObject(Object o) { 123 newObjectsClasses.add(o.getClass()); 124 newObjectsIndexes.put(o,new Integer(newObjectsCount++)); 125 } 126 127 boolean isNewObject(Object o) { 128 if( newObjectsIndexes.get(o) == null ) { 129 return false; 130 } else { 131 return true; 132 } 133 } 134 135 } 136 137 138 139 140 141 142 143