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
package org.sdmlib.models.pattern;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.Objects;
import org.sdmlib.models.modelsets.doubleList;
import de.uniks.networkparser.IdMap;
import de.uniks.networkparser.interfaces.AggregatedEntityCreator;
import de.uniks.networkparser.interfaces.SendableEntity;
import de.uniks.networkparser.interfaces.SendableEntityCreator;
import de.uniks.networkparser.list.ObjectSet;
import de.uniks.networkparser.list.SimpleEntity;
import de.uniks.networkparser.list.SimpleKeyValueList;
public class LazyCloneOp
{
private IdMap map = null;
private LinkedHashMap origToCloneMap = new LinkedHashMap();
private LinkedHashMap cloneToOrigMap = new LinkedHashMap();
public LinkedHashMap getOrigToCloneMap()
{
return origToCloneMap;
}
public LinkedHashMap getCloneToOrigMap()
{
return cloneToOrigMap;
}
public Object clone(Object orig)
{
Objects.requireNonNull(map);
Object clone = origToCloneMap.get(orig);
if (clone != null)
{
// already done
return clone;
}
LinkedList climbTodo = new LinkedList();
LinkedList cloneTodo = new LinkedList();
climbTodo.add(orig);
cloneTodo.add(orig);
ObjectSet graph = new ObjectSet();
// try to compute clone graph from first entry of origToCloneMap
if ( ! origToCloneMap.isEmpty())
{
orig = origToCloneMap.keySet().iterator().next();
clone = origToCloneMap.get(orig);
aggregate(graph, clone);
}
else
{
aggregate(graph, orig);
}
while ( ! climbTodo.isEmpty())
{
orig = climbTodo.pollFirst();
// climb up to root and add parents to todo list
SendableEntityCreator simpleCreator = map.getCreatorClass(orig);
if ( ! (simpleCreator instanceof AggregatedEntityCreator))
{
return cloneComponent(graph, orig);
}
AggregatedEntityCreator creator = (AggregatedEntityCreator) simpleCreator;
if (creator.getUpProperties().length == 0 && creator.getDownProperties().length == 0)
{
// orig is not part of the aggregation tree. No sharing. Clone everything
return cloneComponent(graph, orig);
}
for (String upProp : creator.getUpProperties())
{
Object value = creator.getValue(orig, upProp);
if (value != null && value instanceof Collection)
{
for (Object parent : (Collection) value)
{
clone = origToCloneMap.get(parent);
if (clone != null)
{
break;
}
if (graph.contains(parent))
{
// this parent belongs to the clone graph and does not yet have a clone
climbTodo.add(parent);
cloneTodo.add(parent);
}
}
}
}
}
while (! cloneTodo.isEmpty())
{
orig = cloneTodo.pollLast();
AggregatedEntityCreator creator = (AggregatedEntityCreator) map.getCreatorClass(orig);
// create clone
clone = creator.getSendableInstance(false);
graph.remove(orig);
graph.add(clone);
origToCloneMap.put(orig, clone);
cloneToOrigMap.put(clone, orig);
// copy properties
for ( String prop : creator.getProperties())
{
Object value = creator.getValue(orig, prop);
if (value != null && value instanceof Collection)
{
// if our neighbor is currently cloned, we connect to that clone, only.
Object neighborOrig = null;
Object neighborClone = null;
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 (graph.contains(neighbor))
{
if (neighborOrig != null)
{
creator.setValue(orig, prop, neighbor, SendableEntityCreator.REMOVE);
}
creator.setValue(clone, prop, neighbor, "new");
}
}
}
else
{
creator.setValue(clone, prop, value, "new");
}
}
}
return clone;
}
public Object cloneComponent(ObjectSet graph, Object orig)
{
ObjectSet cloneGraph = new ObjectSet();
// first clone objects,
for (Object obj : graph)
{
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 graph, Object root)
{
if (root == null || graph.contains(root))
{
return;
}
SendableEntityCreator plainCreator = map.getCreatorClass(root);
Objects.requireNonNull(plainCreator);
if ( ! (plainCreator instanceof AggregatedEntityCreator))
{
collectComponent(graph, root);
return;
}
graph.add(root);
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);
}
}
else
{
aggregate(graph, 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;
}
}