Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.sdmlib.models.pattern.LazyCloneOp Maven / Gradle / Ivy
Go to download
SDMLib is a light weight modeling library. SDMLib intentionally comes without any tool or editor.
package org.sdmlib.models.pattern;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.Objects;
import java.util.logging.Logger;
import de.uniks.networkparser.IdMap;
import de.uniks.networkparser.interfaces.SendableEntityCreator;
import de.uniks.networkparser.list.ObjectSet;
import de.uniks.networkparser.list.SimpleList;
public class LazyCloneOp
{
private IdMap map = null;
private LinkedHashMap origToCloneMap = new LinkedHashMap();
private LinkedHashMap cloneToOrigMap = new LinkedHashMap();
public void reset()
{
origToCloneMap.clear();
cloneToOrigMap.clear();
}
public LinkedHashMap getOrigToCloneMap()
{
return origToCloneMap;
}
public LinkedHashMap getCloneToOrigMap()
{
return cloneToOrigMap;
}
private ReachabilityGraph reachabilityGraph = null;
public LazyCloneOp(ReachabilityGraph rg)
{
this.reachabilityGraph = rg;
}
public Object clone(Object orig)
{
Objects.requireNonNull(map);
Object clone = origToCloneMap.get(orig);
if (clone != null)
{
// already done
return clone;
}
Object origOrig = orig;
LinkedList climbTodo = new LinkedList();
LinkedList cloneTodo = new LinkedList();
climbTodo.add(orig);
cloneTodo.add(orig);
ObjectSet dynNodes = new ObjectSet();
SimpleList dynEdges = new SimpleList();
// try to compute clone graph from first entry of origToCloneMap
if ( ! origToCloneMap.isEmpty())
{
orig = origToCloneMap.keySet().iterator().next();
clone = origToCloneMap.get(orig);
dynNodes.add(clone);
aggregate(dynNodes, dynEdges, reachabilityGraph.getStaticNodes(), clone);
}
else
{
dynNodes.add(orig);
aggregate(dynNodes, dynEdges, reachabilityGraph.getStaticNodes(), orig);
}
while ( ! climbTodo.isEmpty())
{
orig = climbTodo.pollFirst();
// for any dyn edge that points to orig clone its src
for (int i = 0; i < dynEdges.size(); i += 3)
{
Object src = dynEdges.get(i);
Object prop = dynEdges.get(i+1);
Object tgt = dynEdges.get(i+2);
if (tgt == orig)
{
Object srcOrig = cloneToOrigMap.get(src);
Object srcClone = origToCloneMap.get(src);
if (! cloneTodo.contains(src) && srcOrig == null && srcClone == null)
{
climbTodo.add(src);
cloneTodo.add(src);
}
}
}
}
for ( Object o : cloneTodo)
{
SendableEntityCreator creator = map.getCreatorClass(o);
// create clone
clone = creator.getSendableInstance(false);
origToCloneMap.put(o, clone);
cloneToOrigMap.put(clone, o);
}
for ( Object o : cloneTodo)
{
clone = origToCloneMap.get(o);
Objects.requireNonNull(clone);
SendableEntityCreator creator = map.getCreatorClass(o);
// copy properties
for ( String prop : creator.getProperties())
{
Object value = creator.getValue(o, prop);
Object neighborOrig = null;
Object neighborClone = null;
if (value != null && value instanceof Collection)
{
// if our neighbor is currently cloned, we connect to that clone, only.
ArrayList list = new ArrayList(((Collection)value).size());
list.addAll((Collection)value);
for (Object neighbor : (Collection)list)
{
neighborClone = origToCloneMap.get(neighbor);
neighborOrig = cloneToOrigMap.get(neighbor);
if (neighborOrig != null)
{
Logger.getGlobal().warning("x is about to be cloned, but points already to a clone. That should not happen");
}
else if (neighborClone == null)
{
// our clone should point to the neigbor
creator.setValue(clone, prop, neighbor, "new");
}
else
{
// our clone should point to the neighborClone
creator.setValue(clone, prop, neighborClone, "new");
}
}
}
else
{
neighborClone = origToCloneMap.get(value);
if (neighborClone == null)
{
// our clone should point to the value
creator.setValue(clone, prop, value, "new");
}
else
{
// our clone should point to the neighborClone
creator.setValue(clone, prop, neighborClone, "new");
}
}
}
// redirect incoming unidirectional edges
for (int i = 0; i < dynEdges.size(); i += 3)
{
Object src = dynEdges.get(i);
String prop = (String) dynEdges.get(i+1);
Object tgt = dynEdges.get(i+2);
if (tgt == o)
{
// if source is a clone
Object srcOrig = cloneToOrigMap.get(src);
if (srcOrig != null)
{
// src should point to clone
SendableEntityCreator srcCreator = map.getCreatorClass(src);
// in case of to-many remove old edge, first
Object value = srcCreator.getValue(src, prop);
if (value instanceof Collection)
{
srcCreator.setValue(src, prop, o, SendableEntityCreator.REMOVE);
}
srcCreator.setValue(src, prop, clone, "new");
}
}
}
}
clone = origToCloneMap.get(origOrig);
return clone;
}
public Object cloneComponent(ObjectSet dynNodes, Object orig)
{
ObjectSet cloneGraph = new ObjectSet();
// first clone objects,
for (Object obj : dynNodes)
{
Object origObj = cloneToOrigMap.get(obj);
if (origObj != null)
{
// obj is already a clone
cloneGraph.add(obj);
continue;
}
Object cloneObj = origToCloneMap.get(obj);
if (cloneObj != null)
{
cloneGraph.add(cloneObj);
continue;
}
// ok, let's clone
SendableEntityCreator creator = map.getCreatorClass(obj);
cloneObj = creator.getSendableInstance(false);
cloneGraph.add(cloneObj);
origToCloneMap.put(obj, cloneObj);
cloneToOrigMap.put(cloneObj, obj);
}
// second clone properties
for (Object clone : cloneGraph)
{
SendableEntityCreator creator = map.getCreatorClass(clone);
Object origObj = cloneToOrigMap.get(clone);
for (String prop : creator.getProperties())
{
Object value = creator.getValue(origObj, prop);
if (value instanceof Collection)
{
for (Object valueObj : (Collection) value)
{
Object cloneValue = origToCloneMap.get(valueObj);
creator.setValue(clone, prop, cloneValue, "new");
}
}
else
{
Object cloneValue = origToCloneMap.get(value);
if (cloneValue == null)
{
creator.setValue(clone, prop, value, "new");
}
else
{
creator.setValue(clone, prop, cloneValue, "new");
}
}
}
}
return origToCloneMap.get(orig);
}
private boolean arrayContains(String[] upProperties, String prop)
{
for (String elem : upProperties)
{
if (elem.equals(prop))
{
return true;
}
}
return false;
}
public IdMap getMap()
{
return map;
}
public LazyCloneOp setMap(IdMap map)
{
this.map = map;
return this;
}
public void aggregate(ObjectSet dynNodes, SimpleList dynEdges, ObjectSet staticNodes, Object root)
{
if (root == null)
{
return;
}
SendableEntityCreator plainCreator = map.getCreatorClass(root);
Objects.requireNonNull(plainCreator);
for (String prop : plainCreator.getProperties())
{
Object value = plainCreator.getValue(root, prop);
if (value != null && value instanceof Collection)
{
for (Object elem : (Collection) value)
{
if ( ! staticNodes.contains(elem))
{
dynEdges.add(root, prop, elem);
if (! dynNodes.contains(elem))
{
dynNodes.add(elem);
aggregate(dynNodes, dynEdges, staticNodes, elem);
}
}
}
}
else
{
// better getCreator() != null
// if ( value != null
// && ! value.getClass().getName().startsWith("java.lang.")
// && ! staticNodes.contains(value)
// && ! (value.getClass().isEnum()))
SendableEntityCreator valueCreator = map.getCreatorClass(value);
if (valueCreator != null)
{
// model type
dynEdges.add(root, prop, value);
if ( ! dynNodes.contains(value))
{
dynNodes.add(value);
aggregate(dynNodes, dynEdges, staticNodes, value);
}
}
}
}
}
private boolean isContained(String[] downProperties, String prop)
{
for (String p : downProperties)
{
if (p.equals(prop))
{
return true;
}
}
return false;
}
// public void aggregate(SimpleKeyValueList graph, Object root, Object parent)
// {
// if (root == null || graph.get(root) != null)
// {
// return;
// }
//
// SendableEntityCreator plainCreator = map.getCreatorClass(root);
//
// Objects.requireNonNull(plainCreator);
//
// if ( ! (plainCreator instanceof AggregatedEntityCreator))
// {
// collectComponent(graph, root);
//
// return;
// }
//
// graph.put(root, parent);
//
// AggregatedEntityCreator creator = (AggregatedEntityCreator) map.getCreatorClass(root);
//
// String[] downProperties = creator.getDownProperties();
//
// for (String prop : downProperties)
// {
// Object value = creator.getValue(root, prop);
//
// if (value != null && value instanceof Collection)
// {
// for (Object elem : (Collection) value)
// {
// aggregate(graph, elem, root);
// }
// }
// else
// {
// aggregate(graph, value, root);
// }
// }
//
// }
public void dynCollectComponent(ObjectSet dynNodes, ArrayList dynEdges, ObjectSet staticNodes, Object root)
{
if (root == null)
{
return;
}
// TODO collect edges
// TODO deal with old staticNodes
SendableEntityCreator creator = map.getCreatorClass(root);
dynNodes.add(root);
String[] properties = creator.getProperties();
for (String prop : properties)
{
Object value = creator.getValue(root, prop);
if (value != null && value instanceof Collection)
{
for (Object elem : (Collection) value)
{
dynCollectComponent(dynNodes, dynEdges, staticNodes, elem);
}
}
else
{
SendableEntityCreator valueCreator = map.getCreatorClass(value);
if (valueCreator != null)
{
dynCollectComponent(dynNodes, dynEdges, staticNodes, value);
}
}
}
}
public void collectComponent(ObjectSet graph, Object root)
{
if (root == null || graph.contains(root))
{
return;
}
SendableEntityCreator creator = map.getCreatorClass(root);
graph.add(root);
String[] properties = creator.getProperties();
for (String prop : properties)
{
Object value = creator.getValue(root, prop);
if (value != null && value instanceof Collection)
{
for (Object elem : (Collection) value)
{
collectComponent(graph, elem);
}
}
else
{
SendableEntityCreator valueCreator = map.getCreatorClass(value);
if (valueCreator != null)
{
collectComponent(graph, value);
}
}
}
}
public LazyCloneOp clear()
{
origToCloneMap.clear();
cloneToOrigMap.clear();
return this;
}
}