/**
*
*/
package it.xsemantics.runtime;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
/**
* Keeps a trace of applied rules (and also failures)
*
* @author Lorenzo Bettini
*
*/
public class RuleApplicationTrace {
private static final String DEEP_CLONING = "deep cloning of trace disabled";
private static final Logger LOGGER = Logger.getLogger(RuleApplicationTrace.class);
protected List<Object> trace = new ArrayList<Object>();
public RuleApplicationTrace() {
}
public void addToTrace(Object traceElement) {
if (traceElement != null) {
trace.add(traceElement);
}
}
public void addAsSubtrace(RuleApplicationTrace subTrace) {
if (subTrace != null) {
trace.add(subTrace);
}
}
/**
* @since 1.5
*/
public void addObjectAsSubtrace(Object traceElement) {
if (traceElement != null) {
RuleApplicationTrace subTrace = new RuleApplicationTrace();
subTrace.addToTrace(traceElement);
trace.add(subTrace);
}
}
public List<Object> getTrace() {
return trace;
}
/**
* @since 1.5
*/
public boolean isEmpty() {
return trace.isEmpty();
}
/**
* Returns a "snapshot" of the current trace (i.e., it partially deeply clones
* possible subtraces); this is useful for storing snapshots in cached
* computations.
*
* If there are instantiation exceptions during the deep cloning of a
* RuleApplicationTrace, e.g., {@link InstantiationException} or
* {@link IllegalAccessException}, the clone gracefully falls back to the
* very same instance.
*
* Note that only possibly nested RuleApplicationTrace instances are cloned,
* not the other objects of the trace, i.e., strings are not cloned.
*
* @since 1.5
*/
public RuleApplicationTrace snapshot() {
return performSafeDeepCloning();
}
/**
* @since 1.6
*/
protected RuleApplicationTrace performSafeDeepCloning() {
RuleApplicationTrace cloned = null;
try {
cloned = getClass().newInstance();
} catch (InstantiationException e) {
LOGGER.info(DEEP_CLONING, e);
return this;
} catch (IllegalAccessException e) {
LOGGER.info(DEEP_CLONING, e);
return this;
}
cloned.trace = new ArrayList<Object>();
for (Object orig : trace) {
if (orig instanceof RuleApplicationTrace) {
cloned.trace.add(((RuleApplicationTrace)orig).performSafeDeepCloning());
} else {
cloned.trace.add(orig);
}
}
return cloned;
}
}