public Network clone() throws CloneNotSupportedException {
NetworkImpl result = (NetworkImpl) super.clone();
result.myNodeMap = new HashMap<String, Node>(10);
for (Node oldNode : myNodeMap.values()) {
Node newNode = oldNode.clone();
result.myNodeMap.put(newNode.getName(), newNode);
newNode.addChangeListener(result);
}
//TODO: Exposed states aren't handled currently, pending redesign of Probes (it should be possible
// to probe things that are nested deeply, in which case exposing state woulnd't be necessary)
// result.myProbeables
// result.myProbeableStates
//TODO: this works with a single Projection impl & no params; should add Projection.copy(Origin, Termination, Network)?
result.myProjectionMap = new HashMap<Termination, Projection>(10);
for (Projection oldProjection : getProjections()) {
try {
Origin newOrigin = result.getNode(oldProjection.getOrigin().getNode().getName())
.getOrigin(oldProjection.getOrigin().getName());
Termination newTermination = result.getNode(oldProjection.getTermination().getNode().getName())
.getTermination(oldProjection.getTermination().getName());
Projection newProjection = new ProjectionImpl(newOrigin, newTermination, result);
result.myProjectionMap.put(newTermination, newProjection);
} catch (StructuralException e) {
throw new CloneNotSupportedException("Problem copying Projectio: " + e.getMessage());
}
}
result.myExposedOrigins = new HashMap<String, Origin>(10);
result.myExposedOriginNames = new HashMap<Origin, String>(10);
result.OrderedExposedOrigins = new LinkedList <Origin> ();
for (Origin exposed : getOrigins()) {
String name = exposed.getName();
Origin wrapped = ((OriginWrapper) exposed).getWrappedOrigin();
try {
// Check to see if referenced node is the network itself. If it is, handle the origin differently.
if (wrapped.getNode().getName() != myName ) {
Origin toExpose = result.getNode(wrapped.getNode().getName()).getOrigin(wrapped.getName());
result.exposeOrigin(toExpose, name);
}
} catch (StructuralException e) {
throw new CloneNotSupportedException("Problem exposing Origin: " + e.getMessage());
}
}
result.myExposedTerminations = new HashMap<String, Termination>(10);
result.myExposedTerminationNames = new HashMap<Termination, String>(10);
result.OrderedExposedTerminations = new LinkedList <Termination> ();
for (Termination exposed : getTerminations()) {
String name = exposed.getName();
Termination wrapped = ((TerminationWrapper) exposed).getWrappedTermination();
try {
// Check to see if referenced node is the network itself. If it is, handle the termination differently.
if (wrapped.getNode().getName() != myName ) {
Termination toExpose = result.getNode(wrapped.getNode().getName()).getTermination(wrapped.getName());
result.exposeTermination(toExpose, name);
}
} catch (StructuralException e) {
throw new CloneNotSupportedException("Problem exposing Termination: " + e.getMessage());
}
}
result.myListeners = new ArrayList<Listener>(5);
result.myMetaData = new HashMap<String, Object>(10);
for (String key : myMetaData.keySet()) {
Object o = myMetaData.get(key);
if (o instanceof Cloneable) {
Object copy = tryToClone((Cloneable) o);
result.myMetaData.put(key, copy);
} else {
result.myMetaData.put(key, o);
}
}
//TODO: take another look at Probe design (maybe Probeables reference Probes?)
result.mySimulator = mySimulator.clone();
result.mySimulator.initialize(result);
Probe[] oldProbes = mySimulator.getProbes();
for (Probe oldProbe : oldProbes) {
Probeable target = oldProbe.getTarget();
if (target instanceof Node) {
Node oldNode = (Node) target;
if (oldProbe.isInEnsemble()) {
try {
Ensemble oldEnsemble = (Ensemble) getNode(oldProbe.getEnsembleName());
int neuronIndex = -1;
for (int j = 0; j < oldEnsemble.getNodes().length && neuronIndex < 0; j++) {
if (oldNode == oldEnsemble.getNodes()[j]) {
neuronIndex = j;
}
}
result.mySimulator.addProbe(oldProbe.getEnsembleName(), neuronIndex, oldProbe.getStateName(), true);
} catch (SimulationException e) {
ourLogger.warn("Problem copying Probe", e);
} catch (StructuralException e) {
ourLogger.warn("Problem copying Probe", e);
}
} else {
try {
result.mySimulator.addProbe(oldNode.getName(), oldProbe.getStateName(), true);
} catch (SimulationException e) {
ourLogger.warn("Problem copying Probe", e);
}
}
} else {