use of easik.model.constraint.ProductConstraint in project fql by CategoricalData.
the class SketchHandler method startElement.
/**
* Overloaded method that is called any time the start of an element is
* found
*
* @param namespace
* @see org.xml.sax.helpers.DefaultHandler
* @param localName
* @see org.xml.sax.helpers.DefaultHandler
* @param qName
* @see org.xml.sax.helpers.DefaultHandler
* @param atts
* @see org.xml.sax.helpers.DefaultHandler
*/
@Override
public void startElement(String namespace, String localName, String qName, Attributes atts) {
_currNode = qName;
if (qName.equals("entity")) {
String name = atts.getValue("name");
int x = Integer.parseInt(atts.getValue("x"));
int y = Integer.parseInt(atts.getValue("y"));
if (_entityNodes.containsKey(name)) {
System.err.println("Duplicate nodes found in XML");
return;
}
_newNode = new EntityNode(name, x, y, _theFrame.getMModel());
_entityNodes.put(name, _newNode);
_curNodeAtts = new LinkedHashMap<>();
} else if (qName.equals("attribute")) {
EasikType type;
// attributeType was created by old Easik versions, and is the SQL
// type signature
// (such as "VARCHAR(255)"). Easik now uses attributeTypeClass,
// containing the
// class name, and any number of extra attributes which
// EasikType.newType() uses to
// recreate the appropriate EasikType object.
String typesig = atts.getValue("attributeType");
if (typesig != null) {
type = EasikType.typeFromSignature(typesig);
} else {
String typename = atts.getValue("attributeTypeClass");
try {
type = EasikType.newType(typename, attributeMap(atts, "attributeType", "attributeTypeClass", "name"));
} catch (ClassNotFoundException e) {
System.err.println("Invalid type found in XML: '" + typename + "' (" + e.getMessage() + ")");
return;
}
}
EntityAttribute<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> myAtt = new EntityAttribute<>(atts.getValue("name"), type, _newNode);
_curNodeAtts.put(atts.getValue("name"), myAtt);
_newNode.addEntityAttribute(myAtt);
} else if (qName.equals("uniqueKey")) {
// New EASIK has noderef, telling us what we refer to. In old easik,
// uniqueKey is under
// the node itself (but as a result, cannot contain edge
// references).
String noderef = atts.getValue("noderef");
if (noderef != null) {
// Restore _newNode and _curNodeAtts, since we're going to need
// them:
_newNode = _entityNodes.get(noderef);
_curNodeAtts = new LinkedHashMap<>();
for (EntityAttribute<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> att : _newNode.getEntityAttributes()) {
_curNodeAtts.put(att.getName(), att);
}
}
_curUniqueKeyName = atts.getValue("name");
_curUniqueKeyElems = new LinkedList<>();
} else if (qName.equals("attref")) {
_curUniqueKeyElems.add(_curNodeAtts.get(atts.getValue("name")));
} else if (qName.equals("edgekeyref")) {
SketchEdge e = _edges.get(atts.getValue("id"));
if (e instanceof UniqueIndexable) {
_curUniqueKeyElems.add((UniqueIndexable) e);
} else {
System.err.println("Encountered an non-unique-indexable <edgekeyref> " + e);
}
} else if (qName.equals("edge")) {
SketchEdge newEdge;
String edgeType = atts.getValue("type");
// injective is an old EASIK attribute:
String injective = atts.getValue("injective");
if (injective != null) {
edgeType = atts.getValue("injective").equals("true") ? "injective" : "normal";
}
EntityNode source = _entityNodes.get(atts.getValue("source"));
EntityNode target = _entityNodes.get(atts.getValue("target"));
String id = atts.getValue("id");
String cascadeAtt = atts.getValue("cascade");
if (cascadeAtt == null) {
// This is from an export before Easik had per-edge cascading
// (in other words, before r583)
// We use the global preferences for cascading
String key = "sql_cascade", def = "restrict";
if (edgeType.equals("partial")) {
key = "sql_cascade_partial";
def = "set_null";
}
cascadeAtt = Easik.getInstance().getSettings().getProperty(key, def);
}
SketchEdge.Cascade cascade = cascadeAtt.equals("set_null") ? SketchEdge.Cascade.SET_NULL : cascadeAtt.equals("cascade") ? SketchEdge.Cascade.CASCADE : SketchEdge.Cascade.RESTRICT;
if (edgeType.equals("injective")) {
newEdge = new InjectiveEdge(source, target, id, cascade);
} else if (edgeType.equals("partial")) {
newEdge = new PartialEdge(source, target, id, cascade);
} else {
newEdge = new NormalEdge(source, target, id, cascade);
}
_edges.put(id, newEdge);
} else if (qName.equals("path")) {
_curPath = new LinkedList<>();
_curPathId = atts.getValue("id");
_curDomain = _entityNodes.get(atts.getValue("domain"));
} else if (qName.equals("edgeref")) {
_curPath.add(_edges.get(atts.getValue("id")));
} else if (// TRIANGLES
qName.equals("sumconstraint") || qName.equals("pullbackconstraint") || qName.equals("productconstraint") || qName.equals("commutativediagram") || qName.equals("equalizerconstraint") || qName.equals("limitconstraint")) // CF2012
{
_curConstraintX = Integer.parseInt(atts.getValue("x"));
_curConstraintY = Integer.parseInt(atts.getValue("y"));
_curConstraintVisible = atts.getValue("isVisible").equals("true");
_curConstraintPaths = new ArrayList<>();
_allConstraintsVisible = atts.getValue("isVisible").equals("true");
} else if (qName.equals("pathref")) {
// This is for compatibility with old versions of Easik (pre-2.0);
// new versions
// put <path> elements directly inside the various constraint
// elements.
_curConstraintPaths.add(_allPaths.get(atts.getValue("id")));
} else if (qName.equals("connectionParam")) {
_connParams.put(atts.getValue("name"), atts.getValue("value"));
} else if (qName.equals("synchronized")) {
// The existance of this tag tells us the sketch is synchronized
_curSketchSync = true;
}
}
use of easik.model.constraint.ProductConstraint in project fql by CategoricalData.
the class EntityNode method getShadowEdges.
/**
* This method returns the edges that will be "shadowed" in this entity for
* allowing various types of constraints. The problem arises when we have
* something like: A -> B -> C, where A is the summand of B, but B has
* to be specified. In this case, the B to C edge will be returned as a
* "shadow" edge. We handle this for other constraint types, too. For a
* good, working, technical example, see the shadowEdges.easik sample
* sketch.
*
* @return a set of edges that will be shadowed by this entity node.
*
* Removing shadow edges completely. Started by Sarah Van der Laan
* continued by Federico Mora because a partial solution is worse
* than all or nothing
*
* public LinkedHashSet<SketchEdge> getShadowEdges() { return
* getShadowEdges(new LinkedHashSet<EntityNode>(5), new
* LinkedHashSet<SketchEdge>(5)); }
*/
// Package-only implementation of the above that breaks recursion by
// ignoring
// shadowed nodes that we already know about.
/**
* @param ignore
* @param constraintEdges
*
* @return
*/
LinkedHashSet<SketchEdge> getShadowEdges(final Collection<EntityNode> ignore, final LinkedHashSet<SketchEdge> constraintEdges) {
// These are the other entity node that we (potentially) need to shadow:
final Collection<EntityNode> shadow = new LinkedHashSet<>(10);
CONSTRAINT: for (final ModelConstraint<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> c : getMModel().getConstraints().values()) {
if (c instanceof SumConstraint) {
final SumConstraint<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> s = (SumConstraint<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge>) c;
for (final ModelPath<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> path : s.getPaths()) {
// for this entity, of course):
if (path.getDomain() == this) {
shadow.addAll(path.getEntities());
constraintEdges.addAll(path.getEdges());
continue CONSTRAINT;
}
}
} else if (c instanceof ProductConstraint) {
final ProductConstraint<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> p = (ProductConstraint<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge>) c;
for (final ModelPath<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> path : p.getPaths()) {
// codomains), along each product path
if (path.getCoDomain() == this) {
for (final ModelPath<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> prodPath : p.getPaths()) {
// But we ignore all of the product path edges,
// since they will be automatically generated:
constraintEdges.addAll(prodPath.getEdges());
final Deque<EntityNode> pathNodes = new LinkedList<>();
pathNodes.addAll(prodPath.getEntities());
pathNodes.removeLast();
shadow.addAll(pathNodes);
}
continue CONSTRAINT;
}
}
} else if (c instanceof EqualizerConstraint) {
final EqualizerConstraint<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> e = (EqualizerConstraint<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge>) c;
// injective *edge* doesn't cause that problem).
if (e.getSourceEntity() == this) {
final ModelPath<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> projection = e.getProjection();
shadow.addAll(projection.getEntities());
// Ignore the projection edge itself:
constraintEdges.addAll(projection.getEdges());
continue CONSTRAINT;
}
} else if (c instanceof PullbackConstraint) {
final PullbackConstraint<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> pb = (PullbackConstraint<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge>) c;
// WPBEDIT CF2012
for (int i = 0; i < pb.getWidth(); i++) {
ModelPath<SketchFrame, SketchGraphModel, Sketch, EntityNode, SketchEdge> proj = pb.getProjectionPath(i);
if (this == proj.getCoDomain()) {
for (int j = 0; j < pb.getWidth(); j++) {
proj = pb.getProjectionPath(j);
Deque<EntityNode> projNodes = new LinkedList<>(proj.getEntities());
projNodes.removeLast();
shadow.addAll(projNodes);
constraintEdges.addAll(proj.getEdges());
}
continue CONSTRAINT;
}
}
} else if (c instanceof LimitConstraint) {
// TRIANGLES TODO CF2012 incomplete
}
}
final LinkedHashSet<SketchEdge> shadowEdges = new LinkedHashSet<>(20);
// All of the ignore entities, plus everything we just found should be
// ignored by any recursion:
final Collection<EntityNode> toIgnore = new LinkedHashSet<>(3);
toIgnore.add(this);
toIgnore.addAll(ignore);
toIgnore.addAll(shadow);
for (final EntityNode node : shadow) {
// it:
if ((node == this) || ignore.contains(node)) {
continue;
}
// Otherwise, shadow its non-partial edges, and all of its shadow
// edges:
shadowEdges.addAll(node.getShadowEdges(toIgnore, constraintEdges));
shadowEdges.addAll(node.getNonPartialEdges());
// Remove edges already
shadowEdges.removeAll(constraintEdges);
// involved in the sum
}
return shadowEdges;
}
Aggregations