package com.google.code.joto.eventrecorder.spy.calls;
import java.io.Serializable;
import java.util.IdentityHashMap;
/**
* binding to replace some objects when recording calls as events
*
* Typical usage examples:
* <ul>
* <li>object not serializable => can not record using Serialization! </li>
* <li>global singleton objects from application</li>
* <li>singleton objects defined in Spring application context</li>
* <li>special wrapper objects use to call methods (rmi stub, ejb remote/local, proxy, aop, ...)</li>
* </ul>
*
* Implementation note:
* This is much less general than the overriding java.io.ObjectOutputStream mecanism.
* It is used only for serializing Method Calls.
* It is not recursive (sub object in a complex graph are not replaced...only top-level objects in calls)
*
*/
public class ObjectReplacementMap {
public static class ObjectInstanceReplacement implements Serializable {
/** internal for java.io.Serializable */
private static final long serialVersionUID = 1L;
private String replacedObjName;
private Serializable replacedObjData;
public ObjectInstanceReplacement(String replacedObjName, Serializable replacedObjData) {
this.replacedObjName = replacedObjName;
this.replacedObjData = replacedObjData;
}
public String getReplacedObjName() {
return replacedObjName;
}
public Serializable getReplacedObjData() {
return replacedObjData;
}
}
private IdentityHashMap<Object, ObjectInstanceReplacement>
objectInstanceReplacements = new IdentityHashMap<Object, ObjectInstanceReplacement>();
//-------------------------------------------------------------------------
public ObjectReplacementMap() {
}
//-------------------------------------------------------------------------
public void addObjectInstanceReplacement(Object targetObj, String replacedObjName, Serializable replacedObjData) {
ObjectInstanceReplacement repl = new ObjectInstanceReplacement(replacedObjName, replacedObjData);
objectInstanceReplacements.put(targetObj, repl);
}
public Object checkReplace(Object obj) {
ObjectInstanceReplacement tmp = objectInstanceReplacements.get(obj);
if (tmp != null) {
return tmp;
}
return obj;
}
public Object[] checkReplaceArray(Object[] objs) {
Object[] res = objs;
if (objs != null && objs.length != 0) {
for(int i = 0, len = objs.length; i < len; i++) {
Object elt = objs[i];
Object tmpelt = checkReplace(elt);
if (tmpelt != elt) {
// do at least one replacement.. check/copy array
if (res == objs) {
Object[] prevres = res;
res = new Object[len];
System.arraycopy(prevres, 0, res, 0, len);
}
res[i] = tmpelt;
}
}
}
return res;
}
}