use of gov.sandia.n2a.db.MPersistent in project n2a by frothga.
the class MPart method inherit.
/**
* Injects inherited equations as children of this node.
* Handles recursion up the hierarchy of parents.
* @param visited Used to guard against a document loading itself.
* @param root The node in the collated tree (named "$inherit") which triggered the current
* round of inheritance. May be a child of a higher node, or a child of this node, but never a child
* of a lower node.
* @param from The $inherit node to be processed. We parse this into a set of part names
* which we retrieve from the database.
*/
public synchronized void inherit(LinkedList<MPersistent> visited, MPart root, MNode from) {
boolean maintainable = from == root && root.isFromTopDocument();
// Indicates that at least one name changed due to ID resolution. This lets us delay updating the field until all names are processed.
boolean changedName = false;
String[] parentNames = from.get().split(",");
for (int i = 0; i < parentNames.length; i++) {
String parentName = parentNames[i];
String id = from.get(i);
parentName = parentName.trim().replace("\"", "");
MPersistent parentSource = (MPersistent) AppData.models.child(parentName);
String parentID = "";
if (parentSource != null) {
parentID = parentSource.get("$metadata", "id");
// Even though the name matches, parentSource is not really the same model that was originally linked.
if (!id.isEmpty() && !parentID.equals(id))
parentSource = null;
}
if (parentSource == null) {
if (!id.isEmpty()) {
parentSource = AppData.getModel(id);
if (// relink
parentSource != null && maintainable) {
parentNames[i] = "\"" + parentSource.key() + "\"";
changedName = true;
}
}
} else {
if (id.isEmpty() && !parentID.isEmpty() && maintainable)
root.set(i, parentID);
}
if (parentSource != null && !visited.contains(parentSource)) {
underrideChildren(root, parentSource);
MPersistent parentFrom = (MPersistent) parentSource.child("$inherit");
if (parentFrom != null) {
visited.push(parentSource);
// yes, we continue to treat the root as the initiator for all the inherited equations
inherit(visited, root, parentFrom);
visited.pop();
}
}
}
if (changedName) {
StringBuilder value = new StringBuilder();
value.append(parentNames[0]);
for (int i = 1; i < parentNames.length; i++) value.append("," + parentNames[i]);
root.source.set(value.toString());
}
}
use of gov.sandia.n2a.db.MPersistent in project n2a by frothga.
the class MPart method set.
public synchronized MNode set(String index, String value) {
MPart result = null;
if (children != null)
result = (MPart) children.get(index);
if (result != null) {
result.set(value);
return result;
}
// We don't have the child, so by construction it is not in any source document.
// ensures that source is a member of the top-level document tree
override();
MPersistent s = (MPersistent) source.set(index, value);
result = new MPart(this, null, s);
if (children == null)
children = new TreeMap<String, MNode>(comparator);
children.put(index, result);
if (// We've created an $inherit line, so load the inherited equations.
index.equals("$inherit")) {
result.getIDs();
// Purge is unnecessary because "result" is a new entry. There is no previous $inherit line.
expand();
}
return result;
}
use of gov.sandia.n2a.db.MPersistent in project n2a by frothga.
the class MPart method move.
public synchronized void move(String fromIndex, String toIndex) {
if (toIndex.equals(fromIndex))
return;
// By definition, no top-level document nodes are allowed to remain at the destination. However, underrides may exist.
clear(toIndex);
MPart fromPart = (MPart) child(fromIndex);
if (fromPart == null)
return;
// We only move top-document nodes.
if (!fromPart.isFromTopDocument())
return;
MNode fromDoc = source.child(fromIndex);
MNode toPart = child(toIndex);
if (// No node at the destination, so merge at level of top-document.
toPart == null) {
MPersistent toDoc = (MPersistent) source.set(toIndex, "");
toDoc.merge(fromDoc);
MPart c = new MPart(this, null, toDoc);
children.put(toIndex, c);
// The sub-tree is empty, so all injected nodes are new. They don't really underride anything.
c.underrideChildren(null, toDoc);
c.expand();
} else // Some existing underrides, so merge in collated tree. This is more expensive because it involves multiple calls to set().
{
toPart.merge(fromDoc);
}
clear(fromIndex);
}
use of gov.sandia.n2a.db.MPersistent in project n2a by frothga.
the class MPart method underrideChildren.
/**
* Injects inherited equations as children of this node.
* Handles recursion down our containment hierarchy.
* See note on underride(MPart,MPersistent). This is safe to run more than once for a given $inherit statement.
* @param newSource The current node in the source document which matches this node in the MPart tree.
*/
public synchronized void underrideChildren(MPart from, MPersistent newSource) {
if (newSource.size() == 0)
return;
if (children == null)
children = new TreeMap<String, MNode>(comparator);
for (MNode n : newSource) {
String key = n.key();
MPersistent p = (MPersistent) n;
MPart c = (MPart) children.get(key);
if (c == null) {
c = new MPart(this, from, p);
children.put(key, c);
c.underrideChildren(from, p);
} else {
c.underride(from, p);
}
}
}
use of gov.sandia.n2a.db.MPersistent in project n2a by frothga.
the class PartMap method build.
/**
* Scans model database and collects parts which are tagged for neuroml.
* This mapping really ought to be updated every time a tagged part is edited.
* However, in normal use (not during library development) the parts will be read-only,
* so one-time initialization should be sufficient.
*/
public void build() {
for (MNode c : AppData.models) {
// Must directly declare a NeuroML part to be included.
if (c.child("$metadata", "backend.lems.part") == null)
continue;
// Create map using fully-collated part, not just the immediate one.
NameMap map = new NameMap(new MPart((MPersistent) c));
outward.put(map.internal, map);
for (String n : map.neuroml) inward.put(n, map);
}
// Determine which parts can be contained by other parts.
for (NameMap map : outward.values()) {
for (String childName : map.children) {
NameMap childMap = outward.get(childName);
if (childMap != null)
childMap.containers.add(map);
}
}
// Child parts add name mappings for variables visible from their containers.
for (NameMap map : outward.values()) map.inheritContainers(this);
for (NameMap map : outward.values()) map.buildContainerMappings();
}
Aggregations