if (cascadeTypes.contains(cascadePermission.get(eventType).get(0))
|| cascadeTypes.contains(cascadePermission.get(eventType).get(1)))
{
Relation.ForeignKey multiplicity = nodeLink.getMultiplicity();
Node childNode = children.get(nodeLink);
switch (multiplicity)
{
case ONE_TO_ONE:
oneToOneChildren.put(nodeLink, childNode);
break;
case ONE_TO_MANY:
oneToManyChildren.put(nodeLink, childNode);
break;
case MANY_TO_ONE:
manyToOneChildren.put(nodeLink, childNode);
break;
case MANY_TO_MANY:
manyToManyChildren.put(nodeLink, childNode);
break;
}
}
}
// Process One-To-Many children
for (NodeLink nodeLink : oneToManyChildren.keySet())
{
// Process child node Graph recursively first
Node childNode = children.get(nodeLink);
if (childNode != null && !childNode.isTraversed())
{
addNodesToFlushStack(childNode, eventType);
}
}
// Process Many-To-Many children
for (NodeLink nodeLink : manyToManyChildren.keySet())
{
if (!node.isTraversed() && !(Boolean) nodeLink.getLinkProperty(LinkProperty.IS_RELATED_VIA_JOIN_TABLE))
{
// Push this node to stack
node.setTraversed(true);
stackQueue.push(node);
logEvent(node, eventType);
}
Node childNode = children.get(nodeLink);
if (childNode != null)
{
// Extract information required to be persisted into
// Join
// Table
if (node.isDirty() && !node.isTraversed())
{
// M-2-M relation fields that are Set or List are joined
// by join table.
// M-2-M relation fields that are Map aren't joined by
// Join table
JoinTableMetadata jtmd = (JoinTableMetadata) nodeLink
.getLinkProperty(LinkProperty.JOIN_TABLE_METADATA);
if (jtmd != null)
{
String joinColumnName = (String) jtmd.getJoinColumns().toArray()[0];
String inverseJoinColumnName = (String) jtmd.getInverseJoinColumns().toArray()[0];
Object entityId = node.getEntityId();
Object childId = childNode.getEntityId();
Set<Object> childValues = new HashSet<Object>();
childValues.add(childId);
OPERATION operation = null;
if (node.getCurrentNodeState().getClass().equals(ManagedState.class))
{
operation = OPERATION.INSERT;
}
else if (node.getCurrentNodeState().getClass().equals(RemovedState.class))
{
operation = OPERATION.DELETE;
}
addJoinTableData(operation, jtmd.getJoinTableSchema(), jtmd.getJoinTableName(),
joinColumnName, inverseJoinColumnName, node.getDataClass(), entityId, childValues);
}
}
// Process child node Graph recursively first
if (!childNode.isTraversed())
{
addNodesToFlushStack(childNode, eventType);
}
}
}
// Process One-To-One children
for (NodeLink nodeLink : oneToOneChildren.keySet())
{
if (!node.isTraversed())
{
// Push this node to stack
node.setTraversed(true);
stackQueue.push(node);
logEvent(node, eventType);
}
// Process child node Graph recursively
Node childNode = children.get(nodeLink);
addNodesToFlushStack(childNode, eventType);
}
// Process Many-To-One children
for (NodeLink nodeLink : manyToOneChildren.keySet())
{
if (!node.isTraversed())
{
// Push this node to stack
node.setTraversed(true);
stackQueue.push(node);
logEvent(node, eventType);
}
// Child node of this node
Node childNode = children.get(nodeLink);
// Process all parents of child node with Many-To-One
// relationship first
Map<NodeLink, Node> parents = childNode.getParents();
for (NodeLink parentLink : parents.keySet())
{
List<CascadeType> cascadeTypes = (List<CascadeType>) nodeLink.getLinkProperty(LinkProperty.CASCADE);
if (cascadeTypes.contains(cascadePermission.get(eventType).get(0))
|| cascadeTypes.contains(cascadePermission.get(eventType).get(1)))
{
Relation.ForeignKey multiplicity = parentLink.getMultiplicity();
Node parentNode = parents.get(parentLink);
// performOperation(parentNode, eventType);
if (multiplicity.equals(Relation.ForeignKey.MANY_TO_ONE))
{
if (!parentNode.isTraversed() && parentNode.isDirty())
{
addNodesToFlushStack(parentNode, eventType);
}
}
}