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